// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <lib/zircon-internal/thread_annotations.h>
#include <string.h>
#include <zircon/assert.h>

#include <fbl/auto_lock.h>
#include <intel-hda/utils/intel-hda-registers.h>

#include "codec-cmd-job.h"
#include "debug-logging.h"
#include "intel-hda-controller.h"

namespace audio {
namespace intel_hda {

namespace {
fbl::Mutex snapshot_regs_buffer_lock;
ihda_controller_snapshot_regs_resp_t snapshot_regs_buffer TA_GUARDED(snapshot_regs_buffer_lock);
}  // namespace

zx_status_t IntelHDAController::SnapshotRegs(dispatcher::Channel* channel,
                                             const ihda_controller_snapshot_regs_req_t& req) {
  ZX_DEBUG_ASSERT(channel != nullptr);

  // TODO(johngro) : What an enormous PITA.  Every register needs to be
  // accessed with the proper sized transaction on the PCI bus, so we cannot
  // just use memcpy to do this.  Life will be better when we have VMOs in
  // place.  Then, we can implement the IOCTL by simply cloning the reigster
  // VMO (reducing its rights to read-only in the process) and sending it back
  // to the calling process.  The diagnostic util can then put their own
  // cycles on the PCI bus.
  fbl::AutoLock lock(&snapshot_regs_buffer_lock);

  auto regs_ptr = reinterpret_cast<hda_registers_t*>(snapshot_regs_buffer.snapshot);
  auto& out_regs = *regs_ptr;

  static_assert(sizeof(snapshot_regs_buffer.snapshot) == sizeof(hda_registers_t),
                "Register snapshot buffer size does not match  register file size!");

  snapshot_regs_buffer.hdr = req.hdr;
  memset(&out_regs, 0, sizeof(out_regs));

  out_regs.gcap = REG_RD(&regs()->gcap);
  out_regs.vmin = REG_RD(&regs()->vmin);
  out_regs.vmaj = REG_RD(&regs()->vmaj);
  out_regs.outpay = REG_RD(&regs()->outpay);
  out_regs.inpay = REG_RD(&regs()->inpay);
  out_regs.gctl = REG_RD(&regs()->gctl);
  out_regs.wakeen = REG_RD(&regs()->wakeen);
  out_regs.statests = REG_RD(&regs()->statests);
  out_regs.gsts = REG_RD(&regs()->gsts);
  out_regs.outstrmpay = REG_RD(&regs()->outstrmpay);
  out_regs.instrmpay = REG_RD(&regs()->instrmpay);
  out_regs.intctl = REG_RD(&regs()->intctl);
  out_regs.intsts = REG_RD(&regs()->intsts);
  out_regs.walclk = REG_RD(&regs()->walclk);
  out_regs.ssync = REG_RD(&regs()->ssync);
  out_regs.corblbase = REG_RD(&regs()->corblbase);
  out_regs.corbubase = REG_RD(&regs()->corbubase);
  out_regs.corbwp = REG_RD(&regs()->corbwp);
  out_regs.corbrp = REG_RD(&regs()->corbrp);
  out_regs.corbctl = REG_RD(&regs()->corbctl);
  out_regs.corbsts = REG_RD(&regs()->corbsts);
  out_regs.corbsize = REG_RD(&regs()->corbsize);
  out_regs.rirblbase = REG_RD(&regs()->rirblbase);
  out_regs.rirbubase = REG_RD(&regs()->rirbubase);
  out_regs.rirbwp = REG_RD(&regs()->rirbwp);
  out_regs.rintcnt = REG_RD(&regs()->rintcnt);
  out_regs.rirbctl = REG_RD(&regs()->rirbctl);
  out_regs.rirbsts = REG_RD(&regs()->rirbsts);
  out_regs.rirbsize = REG_RD(&regs()->rirbsize);
  out_regs.icoi = REG_RD(&regs()->icoi);
  out_regs.icii = REG_RD(&regs()->icii);
  out_regs.icis = REG_RD(&regs()->icis);
  out_regs.dpiblbase = REG_RD(&regs()->dpiblbase);
  out_regs.dpibubase = REG_RD(&regs()->dpibubase);

  uint16_t gcap = REG_RD(&regs()->gcap);
  unsigned int stream_cnt =
      HDA_REG_GCAP_ISS(gcap) + HDA_REG_GCAP_OSS(gcap) + HDA_REG_GCAP_BSS(gcap);

  for (unsigned int i = 0; i < stream_cnt; ++i) {
    auto& sin = regs()->stream_desc[i];
    auto& sout = out_regs.stream_desc[i];

    sout.ctl_sts.w = REG_RD(&sin.ctl_sts.w);
    sout.lpib = REG_RD(&sin.lpib);
    sout.cbl = REG_RD(&sin.cbl);
    sout.lvi = REG_RD(&sin.lvi);
    sout.fifod = REG_RD(&sin.fifod);
    sout.fmt = REG_RD(&sin.fmt);
    sout.bdpl = REG_RD(&sin.bdpl);
    sout.bdpu = REG_RD(&sin.bdpu);
  }

  return channel->Write(&snapshot_regs_buffer, sizeof(snapshot_regs_buffer));
}

}  // namespace intel_hda
}  // namespace audio
