// Copyright 2023 Google LLC
//
// 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.

/*
 * Disclaimer: This binary is only intended to be used on Nuvoton NPCM7xx BMCs.
 *
 * It could also be extended to support NPCM8xx, but it hasn't been tested with
 * that model BMC.
 *
 * This binary is NOT intended to support Aspeed BMCs.
 */

#include <unistd.h>

#include <stdplus/fd/create.hpp>
#include <stdplus/fd/intf.hpp>
#include <stdplus/fd/managed.hpp>
#include <stdplus/fd/mmap.hpp>

#include <cassert>
#include <cstdint>
#include <cstdio>
#include <format>
#include <stdexcept>

/* Base address for Nuvoton's global control register space. */
#define NPCM7XX_GLOBAL_CTRL_BASE_ADDR 0xF0800000
/* Offset of the PDID register and expected PDID value. */
#define PDID_OFFSET 0x00
#define NPCM7XX_PDID 0x04A92750

/* Register width in bytes. */
#define REGISTER_WIDTH 4

/* Base address for Nuvoton's eSPI register space. */
#define NPCM7XX_ESPI_BASE_ADDR 0xF009F000
/*
 * Offset of the eSPI config (ESPICFG) register, along with host channel enable
 * mask and core channel enable mask.
 */
#define ESPICFG_OFFSET 0x4
#define ESPICFG_HOST_CHANNEL_ENABLE_MASK 0xF0
#define ESPICFG_CORE_CHANNEL_ENABLE_MASK 0x0F
/*
 * Offset of the host independence (ESPIHINDP) register and automatic ready bit
 * mask.
 */
#define ESPIHINDP_OFFSET 0x80
#define ESPI_AUTO_READY_MASK 0xF

namespace
{

using stdplus::fd::MMapAccess;
using stdplus::fd::MMapFlags;
using stdplus::fd::OpenAccess;
using stdplus::fd::OpenFlag;
using stdplus::fd::OpenFlags;
using stdplus::fd::ProtFlag;
using stdplus::fd::ProtFlags;

static void usage(char* name)
{
    std::fprintf(stderr, "Usage: %s [-d]\n", name);
    std::fprintf(stderr, "Enable or disable eSPI bus on NPCM7XX BMC\n");
    std::fprintf(stderr, "This program will enable eSPI by default, unless "
                         "the -d option is used.\n");
    std::fprintf(stderr, "  -d   Disable eSPI\n");
}

/*
 * Get a pointer to the register at the given offset, within the provided
 * memory-mapped I/O space.
 */
static inline volatile uint32_t* getReg(stdplus::fd::MMap& map,
                                        size_t regOffset)
{
    uintptr_t regPtr = reinterpret_cast<uintptr_t>(map.get().data()) +
                       regOffset;
    /* Make sure the register pointer is properly aligned. */
    assert((regPtr & ~(REGISTER_WIDTH - 1)) == regPtr);

    return reinterpret_cast<volatile uint32_t*>(regPtr);
}

static void modifyESPIRegisters(bool disable)
{
    /*
     * We need to make sure this is running on a Nuvoton BMC. To do that, we'll
     * read the product identification (PDID) register.
     */

    /* Find the page that includes the Product ID register. */
    size_t pageSize = sysconf(_SC_PAGE_SIZE);
    size_t pageBase = NPCM7XX_GLOBAL_CTRL_BASE_ADDR / pageSize * pageSize;
    size_t pageOffset = NPCM7XX_GLOBAL_CTRL_BASE_ADDR - pageBase;
    size_t mapLength = pageOffset + PDID_OFFSET + REGISTER_WIDTH;

    auto fd = stdplus::fd::open(
        "/dev/mem", OpenFlags(OpenAccess::ReadWrite).set(OpenFlag::Sync));
    stdplus::fd::MMap pdidMap(fd, mapLength, ProtFlags().set(ProtFlag::Read),
                              MMapFlags(MMapAccess::Shared), pageBase);

    volatile uint32_t* const pdidReg = getReg(pdidMap,
                                              pageOffset + PDID_OFFSET);

    /*
     * Read the PDID register to make sure we're running on a Nuvoton NPCM7xx
     * BMC.
     * Note: This binary would probably work on NPCM8xx, as well, if we also
     * allowed the NPCM8xx PDID, since the register addresses are the same. But
     * that hasn't been tested.
     */
    if (*pdidReg != NPCM7XX_PDID)
    {
        throw std::runtime_error(
            std::format("Unexpected product ID {:#x} != {:#x}", *pdidReg,
                        NPCM7XX_PDID)
                .data());
    }

    /*
     * Find the start of the page that includes the start of the eSPI register
     * space.
     */
    pageBase = NPCM7XX_ESPI_BASE_ADDR / pageSize * pageSize;
    pageOffset = NPCM7XX_ESPI_BASE_ADDR - pageBase;

    mapLength = pageOffset + ESPIHINDP_OFFSET + REGISTER_WIDTH;

    stdplus::fd::MMap espiMap(
        fd, mapLength, ProtFlags().set(ProtFlag::Read).set(ProtFlag::Write),
        MMapFlags(MMapAccess::Shared), pageBase);

    /* Read the ESPICFG register. */
    volatile uint32_t* const espicfgReg = getReg(espiMap,
                                                 pageOffset + ESPICFG_OFFSET);
    uint32_t espicfgValue = *espicfgReg;

    if (disable)
    {
        /*
         * Check if the automatic ready bits are set in the eSPI host
         * independence register (ESPIHINDP).
         */
        volatile uint32_t* const espihindpReg =
            getReg(espiMap, pageOffset + ESPIHINDP_OFFSET);
        uint32_t espihindpValue = *espihindpReg;
        if (espihindpValue & ESPI_AUTO_READY_MASK)
        {
            /*
             * If any of the automatic ready bits are set, we need to disable
             * them, using several steps:
             *   - Make sure the host channel enable and core channel bits are
             *     consistent, in the ESPICFG register, i.e. copy the host
             *     channel enable bits to the core channel enable bits.
             *   - Clear the automatic ready bits in ESPIHINDP.
             */
            uint32_t hostChannelEnableBits = espicfgValue &
                                             ESPICFG_HOST_CHANNEL_ENABLE_MASK;
            espicfgValue |= (hostChannelEnableBits >> 4);
            *espicfgReg = espicfgValue;

            espihindpValue &= ~ESPI_AUTO_READY_MASK;
            *espihindpReg = espihindpValue;
        }

        /* Now disable the core channel enable bits in ESPICFG. */
        espicfgValue &= ~ESPICFG_CORE_CHANNEL_ENABLE_MASK;
        *espicfgReg = espicfgValue;

        fprintf(stderr, "Disabled eSPI bus\n");
    }
    else
    {
        /* Enable eSPI by setting the core channel enable bits in ESPICFG. */
        espicfgValue |= ESPICFG_CORE_CHANNEL_ENABLE_MASK;
        *espicfgReg = espicfgValue;

        fprintf(stderr, "Enabled eSPI bus\n");
    }
}

} // namespace

int main(int argc, char** argv)
{
    int opt;
    bool disable = false;
    while ((opt = getopt(argc, argv, "d")) != -1)
    {
        switch (opt)
        {
            case 'd':
                disable = true;
                break;
            default:
                usage(argv[0]);
                return -1;
        }
    }

    try
    {
        /* Update registers to enable or disable eSPI. */
        modifyESPIRegisters(disable);
    }
    catch (const std::exception& e)
    {
        fprintf(stderr, "Failed to %s eSPI bus: %s\n",
                disable ? "disable" : "enable", e.what());
        return -1;
    }

    return 0;
}
