/*
 * Copyright 2020 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include "data.hpp"
#include "internal/sys.hpp"
#include "pciaccess.hpp"

#include <linux/pci_regs.h>

#include <stdplus/types.hpp>

// Some versions of the linux/pci_regs.h header don't define this
#ifndef PCI_STD_NUM_BARS
#define PCI_STD_NUM_BARS 6
#endif // !PCI_STD_NUM_BARS

namespace host_tool
{

class PciBridgeIntf
{
  public:
    virtual ~PciBridgeIntf() = default;

    virtual void write(const stdplus::span<const std::uint8_t> data) = 0;
    virtual void configure(const ipmi_flash::PciConfigResponse& config) = 0;

    virtual std::size_t getDataLength() = 0;
};

class PciAccessBridge : public PciBridgeIntf
{
  public:
    virtual ~PciAccessBridge();

    virtual void write(const stdplus::span<const std::uint8_t> data) override;
    virtual void
        configure(const ipmi_flash::PciConfigResponse& configResp) override{};

    std::size_t getDataLength() override
    {
        return dataLength;
    }

  protected:
    /**
     * Finds the PCI device matching @a match and saves a reference to it in @a
     * dev. Also maps the memory region described in BAR number @a bar to
     * address @a addr,
     */
    PciAccessBridge(const struct pci_id_match* match, int bar,
                    std::size_t dataOffset, std::size_t dataLength,
                    const PciAccess* pci);

    struct pci_device* dev = nullptr;
    std::uint8_t* addr = nullptr;
    std::size_t size = 0;

  private:
    std::size_t dataOffset;
    std::size_t dataLength;

  protected:
    const PciAccess* pci;
};

class NuvotonPciBridge : public PciAccessBridge
{
  public:
    explicit NuvotonPciBridge(const PciAccess* pciAccess,
                              bool skipBridgeDisable = false) :
        PciAccessBridge(&match, bar, dataOffset, dataLength, pciAccess),
        skipBridgeDisable(skipBridgeDisable)
    {
        enableBridge();
    }

    ~NuvotonPciBridge()
    {
        if (!skipBridgeDisable)
            disableBridge();
    }

  private:
    static constexpr std::uint32_t vid = 0x1050;
    static constexpr std::uint32_t did = 0x0750;
    static constexpr int bar = 0;
    static constexpr struct pci_id_match match
    {
        vid, did, PCI_MATCH_ANY, PCI_MATCH_ANY
    };

    static constexpr pciaddr_t bridge = 0x04;
    static constexpr std::uint8_t bridgeEnabled = 0x02;

    static constexpr std::size_t dataOffset = 0x0;
    static constexpr std::size_t dataLength = 0x4000;

    void enableBridge();
    void disableBridge();

    bool skipBridgeDisable;
};

class AspeedPciBridge : public PciAccessBridge
{
  public:
    explicit AspeedPciBridge(const PciAccess* pciAccess,
                             bool skipBridgeDisable = false) :
        PciAccessBridge(&match, bar, dataOffset, dataLength, pciAccess),
        skipBridgeDisable(skipBridgeDisable)
    {
        enableBridge();
    }

    ~AspeedPciBridge()
    {
        if (!skipBridgeDisable)
            disableBridge();
    }

    void configure(const ipmi_flash::PciConfigResponse& configResp) override;

  private:
    static constexpr std::uint32_t vid = 0x1a03;
    static constexpr std::uint32_t did = 0x2000;
    static constexpr int bar = 1;
    static constexpr struct pci_id_match match
    {
        vid, did, PCI_MATCH_ANY, PCI_MATCH_ANY
    };

    static constexpr std::size_t config = 0x0f000;
    static constexpr std::size_t bridge = 0x0f004;
    static constexpr std::uint32_t bridgeEnabled = 0x1;

    static constexpr std::size_t dataOffset = 0x10000;
    static constexpr std::size_t dataLength = 0x10000;

    void enableBridge();
    void disableBridge();

    bool skipBridgeDisable;
};

} // namespace host_tool
