// Copyright 2020 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

#ifndef ZIRCON_KERNEL_LIB_ACPI_LITE_INCLUDE_LIB_ACPI_LITE_H_
#define ZIRCON_KERNEL_LIB_ACPI_LITE_INCLUDE_LIB_ACPI_LITE_H_

#include <lib/acpi_lite/structures.h>
#include <lib/zx/result.h>
#include <stdint.h>
#include <zircon/types.h>

namespace acpi_lite {

class PhysMemReader;

// Abstract interface for reading ACPI tables.
class AcpiParserInterface {
 public:
  virtual ~AcpiParserInterface() = default;

  // Get the number of tables.
  virtual size_t num_tables() const = 0;

  // Return the i'th table. Return nullptr if the index is out of range.
  //
  // If the return value is non-null, it is guaranteed that the returned
  // pointer |p| points to memory at least |p->length| bytes long.
  virtual const AcpiSdtHeader* GetTableAtIndex(size_t index) const = 0;
};

// Functionality for reading ACPI tables.
class AcpiParser final : public AcpiParserInterface {
 public:
  AcpiParser(const AcpiParser&) = default;
  AcpiParser& operator=(const AcpiParser&) = default;

  // Create a new AcpiParser, using the given PhysMemReader object.
  //
  // PhysMemReader must outlive this object. Caller retains ownership of the PhysMemReader.
  static zx::result<AcpiParser> Init(PhysMemReader& physmem_reader, zx_paddr_t rsdp_pa);

  uint64_t rsdp_pa() const { return rsdp_addr_; }

  // Print tables to debug output.
  void DumpTables() const;

  // |AcpiParserInterface| implementation.
  inline size_t num_tables() const final { return num_tables_; }
  const AcpiSdtHeader* GetTableAtIndex(size_t index) const final;

 private:
  // Create a new AcpiParser.
  //
  // |reader| and |sdt| must outlive the created instance.
  AcpiParser(PhysMemReader& reader, zx_paddr_t rsdp_addr, const AcpiRsdt* rsdt,
             const AcpiXsdt* xsdt, size_t num_tables, zx_paddr_t root_table_addr)
      : reader_(&reader),
        rsdt_(rsdt),
        xsdt_(xsdt),
        num_tables_(num_tables),
        root_table_addr_(root_table_addr),
        rsdp_addr_(rsdp_addr) {}

  // Get the physical address of the given table, or return 0 if the table does not exist.
  zx_paddr_t GetTablePhysAddr(size_t index) const;

  PhysMemReader* reader_;       // Owned elsewhere. Non-null.
  const AcpiRsdt* rsdt_;        // Owned elsewhere. May be null.
  const AcpiXsdt* xsdt_;        // Owned elsewhere. May be null.
  size_t num_tables_;           // Number of top level tables
  zx_paddr_t root_table_addr_;  // Physical address of the root table.
  zx_paddr_t rsdp_addr_;        // Physical address of the RSDP.
};

// Get the first table matching the given signature. Return nullptr if no table found.
const AcpiSdtHeader* GetTableBySignature(const AcpiParserInterface& parser, AcpiSignature sig);

// Get the first table of the given type. Return nullptr if no table found, or the
// table is invalid.,
template <typename T>
const T* GetTableByType(const AcpiParserInterface& parser) {
  const AcpiSdtHeader* header = GetTableBySignature(parser, T::kSignature);
  if (header == nullptr) {
    return nullptr;
  }
  // TODO(https://fxbug.dev/42170568): Change this check so that tables with optional entries can be
  // found on platforms that do not have them
  if (header->length < sizeof(T)) {
    return nullptr;
  }
  return reinterpret_cast<const T*>(header);
}

// A PhysMemReader translates physical addresses (such as those in the ACPI tables and the RSDT
// itself) into pointers directly readable by the acpi_lite library.
class PhysMemReader {
 public:
  virtual ~PhysMemReader() = default;
  virtual zx::result<const void*> PhysToPtr(uintptr_t phys, size_t length) = 0;
};

//
// Functions below exposed for testing.
//

// Ensure the checksum of the given block of code is valid.
bool AcpiChecksumValid(const void* buf, size_t len);

// Calculate a checksum of the given range of memory.
uint8_t AcpiChecksum(const void* _buf, size_t len);

// Validate the RSDT / XSDT tables.
zx::result<const AcpiRsdt*> ValidateRsdt(PhysMemReader& reader, uint32_t rsdt_pa,
                                         size_t* num_tables);
zx::result<const AcpiXsdt*> ValidateXsdt(PhysMemReader& reader, uint64_t xsdt_pa,
                                         size_t* num_tables);

}  // namespace acpi_lite

#endif  // ZIRCON_KERNEL_LIB_ACPI_LITE_INCLUDE_LIB_ACPI_LITE_H_
