<commit_before>#include "config.h"

#include "network_manager.hpp"
#include "rtnetlink_server.hpp"
#include "types.hpp"
#ifdef SYNC_MAC_FROM_INVENTORY
#include "util.hpp"
#endif

#include <linux/netlink.h>

#include <filesystem>
#include <fstream>
#include <functional>
#include <memory>
#ifdef SYNC_MAC_FROM_INVENTORY
#include <nlohmann/json.hpp>
#endif
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/log.hpp>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/bus/match.hpp>
#include <sdbusplus/server/manager.hpp>
#include <sdeventplus/event.hpp>
#include <xyz/openbmc_project/Common/error.hpp>

using phosphor::logging::elog;
using phosphor::logging::entry;
using phosphor::logging::level;
using phosphor::logging::log;
using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
using DbusObjectPath = std::string;
using DbusInterface = std::string;
using PropertyValue = std::string;

constexpr char NETWORK_CONF_DIR[] = "/etc/systemd/network";

constexpr char DEFAULT_OBJPATH[] = "/xyz/openbmc_project/network";

constexpr auto firstBootPath = "/var/lib/network/firstBoot_";
constexpr auto configFile = "/usr/share/network/config.json";

constexpr auto invNetworkIntf =
    "xyz.openbmc_project.Inventory.Item.NetworkInterface";

namespace phosphor
{
namespace network
{

std::unique_ptr<phosphor::network::Manager> manager = nullptr;
std::unique_ptr<Timer> refreshObjectTimer = nullptr;
std::unique_ptr<Timer> reloadTimer = nullptr;

#ifdef SYNC_MAC_FROM_INVENTORY
std::unique_ptr<sdbusplus::bus::match_t> EthInterfaceMatch = nullptr;
std::vector<std::string> first_boot_status;

bool setInventoryMACOnSystem(sdbusplus::bus_t& bus,
                             const nlohmann::json& configJson,
                             const std::string& intfname)
{
    try
    {
        auto inventoryMAC = mac_address::getfromInventory(bus, intfname);
        if (!mac_address::toString(inventoryMAC).empty())
        {
            log<level::INFO>("Mac Address in Inventory on "),
                entry("Interface : ", intfname.c_str()),
                entry("MAC Address :",
                      (mac_address::toString(inventoryMAC)).c_str());
            manager->setFistBootMACOnInterface(std::make_pair(
                intfname.c_str(), mac_address::toString(inventoryMAC)));
            first_boot_status.push_back(intfname.c_str());
            bool status = true;
            for (const auto& keys : configJson.items())
            {
                if (!(std::find(first_boot_status.begin(),
                                first_boot_status.end(),
                                keys.key()) != first_boot_status.end()))
                {
                    log<level::INFO>("Interface MAC is NOT set from VPD"),
                        entry("INTERFACE", keys.key().c_str());
                    status = false;
                }
            }
            if (status)
            {
                log<level::INFO>("Removing the match for ethernet interfaces");
                phosphor::network::EthInterfaceMatch = nullptr;
            }
        }
        else
        {
            log<level::INFO>("Nothing is present in Inventory");
            return false;
        }
    }
    catch (const std::exception& e)
    {
        log<level::ERR>("Exception occurred during getting of MAC "
                        "address from Inventory");
        return false;
    }
    return true;
}

// register the macthes to be monitored from inventory manager
void registerSignals(sdbusplus::bus_t& bus, const nlohmann::json& configJson)
{
    log<level::INFO>("Registering the Inventory Signals Matcher");

    static std::unique_ptr<sdbusplus::bus::match_t> MacAddressMatch;

    auto callback = [&](sdbusplus::message_t& m) {
        std::map<DbusObjectPath,
                 std::map<DbusInterface, std::variant<PropertyValue>>>
            interfacesProperties;

        sdbusplus::message::object_path objPath;
        std::pair<std::string, std::string> ethPair;
        m.read(objPath, interfacesProperties);

        for (const auto& pattern : configJson.items())
        {
            if (objPath.str.find(pattern.value()) != std::string::npos)
            {
                for (auto& interface : interfacesProperties)
                {
                    if (interface.first == invNetworkIntf)
                    {
                        for (const auto& property : interface.second)
                        {
                            if (property.first == "MACAddress")
                            {
                                ethPair = std::make_pair(
                                    pattern.key(),
                                    std::get<std::string>(property.second));
                                break;
                            }
                        }
                        break;
                    }
                }
                if (!(ethPair.first.empty() || ethPair.second.empty()))
                {
                    manager->setFistBootMACOnInterface(ethPair);
                }
            }
        }
    };

    MacAddressMatch = std::make_unique<sdbusplus::bus::match_t>(
        bus,
        "interface='org.freedesktop.DBus.ObjectManager',type='signal',"
        "member='InterfacesAdded',path='/xyz/openbmc_project/"
        "inventory'",
        callback);
}

void watchEthernetInterface(sdbusplus::bus_t& bus,
                            const nlohmann::json& configJson)
{
    auto mycallback = [&](sdbusplus::message_t& m) {
        std::map<DbusObjectPath,
                 std::map<DbusInterface, std::variant<PropertyValue>>>
            interfacesProperties;

        sdbusplus::message::object_path objPath;
        std::pair<std::string, std::string> ethPair;
        m.read(objPath, interfacesProperties);
        for (const auto& interfaces : interfacesProperties)
        {
            if (interfaces.first ==
                "xyz.openbmc_project.Network.EthernetInterface")
            {
                for (const auto& property : interfaces.second)
                {
                    if (property.first == "InterfaceName")
                    {
                        std::string infname =
                            std::get<std::string>(property.second);

                        if (configJson.find(infname) == configJson.end())
                        {
                            // ethernet interface not found in configJSON
                            // check if it is not sit0 interface, as it is
                            // expected.
                            if (infname != "sit0")
                            {
                                log<level::ERR>(
                                    "Wrong Interface Name in Config Json");
                            }
                        }
                        else
                        {
                            if (!phosphor::network::setInventoryMACOnSystem(
                                    bus, configJson, infname))
                            {
                                phosphor::network::registerSignals(bus,
                                                                   configJson);
                                phosphor::network::EthInterfaceMatch = nullptr;
                            }
                        }
                        break;
                    }
                }
                break;
            }
        }
    };
    // Incase if phosphor-inventory-manager started early and the VPD is already
    // collected by the time network service has come up, better to check the
    // VPD directly and set the MAC Address on the respective Interface.

    bool registeredSignals = false;
    for (const auto& interfaceString : configJson.items())
    {
        if (!std::filesystem::exists(firstBootPath + interfaceString.key()) &&
            !registeredSignals)
        {

            log<level::INFO>(
                "First boot file is not present, check VPD for MAC");
            phosphor::network::EthInterfaceMatch = std::make_unique<
                sdbusplus::bus::match_t>(
                bus,
                "interface='org.freedesktop.DBus.ObjectManager',type='signal',"
                "member='InterfacesAdded',path='/xyz/openbmc_project/network'",
                mycallback);
            registeredSignals = true;
        }
    }
}

#endif

/** @brief refresh the network objects. */
void refreshObjects()
{
    if (manager)
    {
        log<level::INFO>("Refreshing the objects.");
        manager->createChildObjects();
        log<level::INFO>("Refreshing complete.");
    }
}

void reloadNetworkd()
{
    if (manager)
    {
        log<level::INFO>("Sending networkd reload");
        manager->doReloadConfigs();
        log<level::INFO>("Done networkd reload");
    }
}

void initializeTimers()
{
    auto event = sdeventplus::Event::get_default();
    refreshObjectTimer =
        std::make_unique<Timer>(event, std::bind(refreshObjects));
    reloadTimer = std::make_unique<Timer>(event, std::bind(reloadNetworkd));
}

} // namespace network
} // namespace phosphor

int main(int /*argc*/, char** /*argv*/)
{
    phosphor::network::initializeTimers();

    auto bus = sdbusplus::bus::new_default();

    // Need sd_event to watch for OCC device errors
    sd_event* event = nullptr;
    auto r = sd_event_default(&event);
    if (r < 0)
    {
        log<level::ERR>("Error creating a default sd_event handler");
        return r;
    }

    phosphor::network::EventPtr eventPtr{event};
    event = nullptr;

    // Attach the bus to sd_event to service user requests
    bus.attach_event(eventPtr.get(), SD_EVENT_PRIORITY_NORMAL);

    // Add sdbusplus Object Manager for the 'root' path of the network manager.
    sdbusplus::server::manager_t objManager(bus, DEFAULT_OBJPATH);
    bus.request_name(DEFAULT_BUSNAME);

    phosphor::network::manager = std::make_unique<phosphor::network::Manager>(
        bus, DEFAULT_OBJPATH, NETWORK_CONF_DIR);

    // create the default network files if the network file
    // is not there for any interface.
    if (phosphor::network::manager->createDefaultNetworkFiles())
    {
        phosphor::network::manager->reloadConfigs();
    }

    // RTNETLINK event handler
    phosphor::network::rtnetlink::Server svr(eventPtr);

#ifdef SYNC_MAC_FROM_INVENTORY
    std::ifstream in(configFile);
    nlohmann::json configJson;
    in >> configJson;
    phosphor::network::watchEthernetInterface(bus, configJson);
#endif

    // Trigger the initial object scan
    // This is intentionally deferred, to ensure that systemd-networkd is
    // fully configured.
    phosphor::network::refreshObjectTimer->restartOnce(
        phosphor::network::refreshTimeout);

    sd_event_loop(eventPtr.get());
}
<commit_msg>main: Catch and handle all exceptions<commit_after>#include "config.h"

#include "network_manager.hpp"
#include "rtnetlink_server.hpp"
#include "types.hpp"
#ifdef SYNC_MAC_FROM_INVENTORY
#include "util.hpp"
#endif

#include <fmt/format.h>
#include <linux/netlink.h>

#include <filesystem>
#include <fstream>
#include <functional>
#include <memory>
#ifdef SYNC_MAC_FROM_INVENTORY
#include <nlohmann/json.hpp>
#endif
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/log.hpp>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/bus/match.hpp>
#include <sdbusplus/server/manager.hpp>
#include <sdeventplus/event.hpp>
#include <xyz/openbmc_project/Common/error.hpp>

using phosphor::logging::elog;
using phosphor::logging::entry;
using phosphor::logging::level;
using phosphor::logging::log;
using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
using DbusObjectPath = std::string;
using DbusInterface = std::string;
using PropertyValue = std::string;

constexpr char NETWORK_CONF_DIR[] = "/etc/systemd/network";

constexpr char DEFAULT_OBJPATH[] = "/xyz/openbmc_project/network";

constexpr auto firstBootPath = "/var/lib/network/firstBoot_";
constexpr auto configFile = "/usr/share/network/config.json";

constexpr auto invNetworkIntf =
    "xyz.openbmc_project.Inventory.Item.NetworkInterface";

namespace phosphor
{
namespace network
{

std::unique_ptr<Manager> manager = nullptr;
std::unique_ptr<Timer> refreshObjectTimer = nullptr;
std::unique_ptr<Timer> reloadTimer = nullptr;

#ifdef SYNC_MAC_FROM_INVENTORY
std::unique_ptr<sdbusplus::bus::match_t> EthInterfaceMatch = nullptr;
std::vector<std::string> first_boot_status;

bool setInventoryMACOnSystem(sdbusplus::bus_t& bus,
                             const nlohmann::json& configJson,
                             const std::string& intfname)
{
    try
    {
        auto inventoryMAC = mac_address::getfromInventory(bus, intfname);
        if (!mac_address::toString(inventoryMAC).empty())
        {
            log<level::INFO>("Mac Address in Inventory on "),
                entry("Interface : ", intfname.c_str()),
                entry("MAC Address :",
                      (mac_address::toString(inventoryMAC)).c_str());
            manager->setFistBootMACOnInterface(std::make_pair(
                intfname.c_str(), mac_address::toString(inventoryMAC)));
            first_boot_status.push_back(intfname.c_str());
            bool status = true;
            for (const auto& keys : configJson.items())
            {
                if (!(std::find(first_boot_status.begin(),
                                first_boot_status.end(),
                                keys.key()) != first_boot_status.end()))
                {
                    log<level::INFO>("Interface MAC is NOT set from VPD"),
                        entry("INTERFACE", keys.key().c_str());
                    status = false;
                }
            }
            if (status)
            {
                log<level::INFO>("Removing the match for ethernet interfaces");
                EthInterfaceMatch = nullptr;
            }
        }
        else
        {
            log<level::INFO>("Nothing is present in Inventory");
            return false;
        }
    }
    catch (const std::exception& e)
    {
        log<level::ERR>("Exception occurred during getting of MAC "
                        "address from Inventory");
        return false;
    }
    return true;
}

// register the macthes to be monitored from inventory manager
void registerSignals(sdbusplus::bus_t& bus, const nlohmann::json& configJson)
{
    log<level::INFO>("Registering the Inventory Signals Matcher");

    static std::unique_ptr<sdbusplus::bus::match_t> MacAddressMatch;

    auto callback = [&](sdbusplus::message_t& m) {
        std::map<DbusObjectPath,
                 std::map<DbusInterface, std::variant<PropertyValue>>>
            interfacesProperties;

        sdbusplus::message::object_path objPath;
        std::pair<std::string, std::string> ethPair;
        m.read(objPath, interfacesProperties);

        for (const auto& pattern : configJson.items())
        {
            if (objPath.str.find(pattern.value()) != std::string::npos)
            {
                for (auto& interface : interfacesProperties)
                {
                    if (interface.first == invNetworkIntf)
                    {
                        for (const auto& property : interface.second)
                        {
                            if (property.first == "MACAddress")
                            {
                                ethPair = std::make_pair(
                                    pattern.key(),
                                    std::get<std::string>(property.second));
                                break;
                            }
                        }
                        break;
                    }
                }
                if (!(ethPair.first.empty() || ethPair.second.empty()))
                {
                    manager->setFistBootMACOnInterface(ethPair);
                }
            }
        }
    };

    MacAddressMatch = std::make_unique<sdbusplus::bus::match_t>(
        bus,
        "interface='org.freedesktop.DBus.ObjectManager',type='signal',"
        "member='InterfacesAdded',path='/xyz/openbmc_project/"
        "inventory'",
        callback);
}

void watchEthernetInterface(sdbusplus::bus_t& bus,
                            const nlohmann::json& configJson)
{
    auto mycallback = [&](sdbusplus::message_t& m) {
        std::map<DbusObjectPath,
                 std::map<DbusInterface, std::variant<PropertyValue>>>
            interfacesProperties;

        sdbusplus::message::object_path objPath;
        std::pair<std::string, std::string> ethPair;
        m.read(objPath, interfacesProperties);
        for (const auto& interfaces : interfacesProperties)
        {
            if (interfaces.first ==
                "xyz.openbmc_project.Network.EthernetInterface")
            {
                for (const auto& property : interfaces.second)
                {
                    if (property.first == "InterfaceName")
                    {
                        std::string infname =
                            std::get<std::string>(property.second);

                        if (configJson.find(infname) == configJson.end())
                        {
                            // ethernet interface not found in configJSON
                            // check if it is not sit0 interface, as it is
                            // expected.
                            if (infname != "sit0")
                            {
                                log<level::ERR>(
                                    "Wrong Interface Name in Config Json");
                            }
                        }
                        else
                        {
                            if (!setInventoryMACOnSystem(bus, configJson,
                                                         infname))
                            {
                                registerSignals(bus, configJson);
                                EthInterfaceMatch = nullptr;
                            }
                        }
                        break;
                    }
                }
                break;
            }
        }
    };
    // Incase if phosphor-inventory-manager started early and the VPD is already
    // collected by the time network service has come up, better to check the
    // VPD directly and set the MAC Address on the respective Interface.

    bool registeredSignals = false;
    for (const auto& interfaceString : configJson.items())
    {
        if (!std::filesystem::exists(firstBootPath + interfaceString.key()) &&
            !registeredSignals)
        {

            log<level::INFO>(
                "First boot file is not present, check VPD for MAC");
            EthInterfaceMatch = std::make_unique<sdbusplus::bus::match_t>(
                bus,
                "interface='org.freedesktop.DBus.ObjectManager',type='signal',"
                "member='InterfacesAdded',path='/xyz/openbmc_project/network'",
                mycallback);
            registeredSignals = true;
        }
    }
}

#endif

/** @brief refresh the network objects. */
void refreshObjects()
{
    if (manager)
    {
        log<level::INFO>("Refreshing the objects.");
        manager->createChildObjects();
        log<level::INFO>("Refreshing complete.");
    }
}

void reloadNetworkd()
{
    if (manager)
    {
        log<level::INFO>("Sending networkd reload");
        manager->doReloadConfigs();
        log<level::INFO>("Done networkd reload");
    }
}

void initializeTimers()
{
    auto event = sdeventplus::Event::get_default();
    refreshObjectTimer =
        std::make_unique<Timer>(event, std::bind(refreshObjects));
    reloadTimer = std::make_unique<Timer>(event, std::bind(reloadNetworkd));
}

int main()
{
    initializeTimers();

    auto bus = sdbusplus::bus::new_default();

    // Need sd_event to watch for OCC device errors
    sd_event* event = nullptr;
    auto r = sd_event_default(&event);
    if (r < 0)
    {
        log<level::ERR>("Error creating a default sd_event handler");
        return r;
    }

    EventPtr eventPtr{event};
    event = nullptr;

    // Attach the bus to sd_event to service user requests
    bus.attach_event(eventPtr.get(), SD_EVENT_PRIORITY_NORMAL);

    // Add sdbusplus Object Manager for the 'root' path of the network manager.
    sdbusplus::server::manager_t objManager(bus, DEFAULT_OBJPATH);
    bus.request_name(DEFAULT_BUSNAME);

    manager = std::make_unique<Manager>(bus, DEFAULT_OBJPATH, NETWORK_CONF_DIR);

    // create the default network files if the network file
    // is not there for any interface.
    if (manager->createDefaultNetworkFiles())
    {
        manager->reloadConfigs();
    }

    // RTNETLINK event handler
    rtnetlink::Server svr(eventPtr);

#ifdef SYNC_MAC_FROM_INVENTORY
    std::ifstream in(configFile);
    nlohmann::json configJson;
    in >> configJson;
    watchEthernetInterface(bus, configJson);
#endif

    // Trigger the initial object scan
    // This is intentionally deferred, to ensure that systemd-networkd is
    // fully configured.
    refreshObjectTimer->restartOnce(refreshTimeout);

    return sd_event_loop(eventPtr.get());
}

} // namespace network
} // namespace phosphor

int main(int /*argc*/, char** /*argv*/)
{
    try
    {
        return phosphor::network::main();
    }
    catch (const std::exception& e)
    {
        auto msg = fmt::format("FAILED: {}", e.what());
        log<level::ERR>(msg.c_str(), entry("ERROR", e.what()));
        return 1;
    }
}
<|endoftext|>


<commit_before>#include "formulation/updater/diffusion_updater.hpp"

namespace bart {

namespace formulation {

namespace updater {

template<int dim>
DiffusionUpdater<dim>::DiffusionUpdater(
    std::unique_ptr<DiffusionFormulationType> formulation_ptr,
    std::shared_ptr<StamperType> stamper_ptr,
    std::unordered_set<problem::Boundary> reflective_boundaries)
    : FixedUpdater<dim>(stamper_ptr),
      formulation_ptr_(std::move(formulation_ptr)),
      stamper_ptr_(stamper_ptr),
      reflective_boundaries_(reflective_boundaries) {
  AssertThrow(formulation_ptr_ != nullptr,
              dealii::ExcMessage("Error in constructor of DiffusionUpdater, "
                                 "formulation pointer passed is null"))
  AssertThrow(stamper_ptr_ != nullptr,
              dealii::ExcMessage("Error in constructor of DiffusionUpdater, "
                                 "stamper pointer passed is null"))
  this->set_description("diffusion formulation updater",
                        utility::DefaultImplementation(true));

  if (!reflective_boundaries_.empty()) {
    this->set_description(this->description() + " (reflective BCs)",
                          utility::DefaultImplementation(true));
  }
}

template<int dim>
auto DiffusionUpdater<dim>::SetUpFixedFunctions(system::System& /*to_update*/,
                                                system::EnergyGroup group,
                                                quadrature::QuadraturePointIndex /*index*/) -> void {
  this->fixed_matrix_functions_ = {};
  this->fixed_vector_functions_ = {};
  this->fixed_matrix_boundary_functions_ = {};
  this->fixed_vector_boundary_functions_ = {};

  const auto streaming_term_function = [&, group](formulation::FullMatrix& cell_matrix, const CellPtr& cell_ptr) -> void {
    formulation_ptr_->FillCellStreamingTerm(cell_matrix, cell_ptr, group.get()); };
  const auto collision_term_function = [&, group](formulation::FullMatrix& cell_matrix, const CellPtr& cell_ptr) -> void {
    formulation_ptr_->FillCellCollisionTerm(cell_matrix, cell_ptr, group.get()); };
  this->fixed_matrix_functions_.push_back(streaming_term_function);
  this->fixed_matrix_functions_.push_back(collision_term_function);

  auto fixed_term_function = [&, group](formulation::Vector& cell_vector, const CellPtr& cell_ptr) -> void {
    formulation_ptr_->FillCellFixedSource(cell_vector, cell_ptr, group.get()); };
  this->fixed_vector_functions_.push_back(fixed_term_function);
  if (this->rhs_constant_vector_ptr_ != nullptr) {
    auto constant_term_function = [=](formulation::Vector& cell_vector, const CellPtr& cell_ptr) -> void {
      formulation_ptr_->FillCellConstantTerm(cell_vector, cell_ptr, *this->rhs_constant_vector_ptr_); };
    this->fixed_vector_functions_.push_back(constant_term_function);
  }

  auto boundary_function = [&](formulation::FullMatrix& cell_matrix, const domain::FaceIndex face_index,
                               const CellPtr& cell_ptr) -> void {
    using DiffusionBoundaryType = typename formulation::scalar::DiffusionI<dim>::BoundaryType;

    DiffusionBoundaryType boundary_type = DiffusionBoundaryType::kInterior;

    if (cell_ptr->at_boundary()) {
      problem::Boundary boundary = static_cast<problem::Boundary>(cell_ptr->face(face_index.get())->boundary_id());
      if (reflective_boundaries_.count(boundary) == 1) {
        boundary_type = DiffusionBoundaryType::kReflective;
      } else {
        boundary_type = DiffusionBoundaryType::kVacuum;
      }
    }

    formulation_ptr_->FillBoundaryTerm(cell_matrix, cell_ptr,face_index.get(), boundary_type);
  };
  this->fixed_matrix_boundary_functions_.push_back(boundary_function);
}

template<int dim>
void DiffusionUpdater<dim>::UpdateScatteringSource(system::System &to_update, const system::EnergyGroup energy_group,
                                                   quadrature::QuadraturePointIndex /*index*/) {
  using system::terms::VariableLinearTerms;
  using CellPtr = typename domain::CellPtr<dim>;
  const int group = energy_group.get();
  auto scattering_source_ptr = to_update.right_hand_side_ptr_->GetVariableTermPtr({group, 0}, VariableLinearTerms::kScatteringSource);
  *scattering_source_ptr = 0;
  const auto& current_moments = to_update.current_moments->moments();
  auto scattering_source_function = [&](formulation::Vector& cell_vector, const CellPtr& cell_ptr) -> void {
        formulation_ptr_->FillCellScatteringSource(cell_vector, cell_ptr, group, current_moments);
  };
  stamper_ptr_->StampVector(*scattering_source_ptr, scattering_source_function);
}
template<int dim>
void DiffusionUpdater<dim>::UpdateFissionSource(system::System &to_update,system::EnergyGroup energy_group,
    quadrature::QuadraturePointIndex /*index*/) {
  using system::terms::VariableLinearTerms;
  using CellPtr = typename domain::CellPtr<dim>;
  const int group = energy_group.get();
  auto fission_source_ptr = to_update.right_hand_side_ptr_->GetVariableTermPtr({group, 0}, VariableLinearTerms::kFissionSource);
  *fission_source_ptr = 0;
  const auto& current_moments = to_update.current_moments->moments();
  const auto& in_group_moment = current_moments.at({group, 0, 0});
  auto fission_source_function = [&](formulation::Vector& cell_vector, const CellPtr& cell_ptr) -> void {
    formulation_ptr_->FillCellFissionSource(cell_vector, cell_ptr, group, to_update.k_effective.value(),
                                            in_group_moment, current_moments);
  };
  stamper_ptr_->StampVector(*fission_source_ptr, fission_source_function);
}
template<int dim>
void DiffusionUpdater<dim>::UpdateFixedSource(
    system::System &to_update,
    system::EnergyGroup energy_group,
    quadrature::QuadraturePointIndex /*index*/) {
  int group = energy_group.get();
  auto fixed_source_ptr =
      to_update.right_hand_side_ptr_->GetFixedTermPtr({group, 0});
  *fixed_source_ptr = 0;
  auto fixed_source_function =
      [&](formulation::Vector& cell_vector,
          const domain::CellPtr<dim> &cell_ptr) -> void {
        formulation_ptr_->FillCellFixedSource(cell_vector,
                                              cell_ptr, group);
      };
  stamper_ptr_->StampVector(*fixed_source_ptr, fixed_source_function);
}

template class DiffusionUpdater<1>;
template class DiffusionUpdater<2>;
template class DiffusionUpdater<3>;

} // namespace updater

} // namespace formulation

} // namespace bart
<commit_msg>Removed extraneous check for boundary term in DiffusionUpdater.<commit_after>#include "formulation/updater/diffusion_updater.hpp"

namespace bart {

namespace formulation {

namespace updater {

template<int dim>
DiffusionUpdater<dim>::DiffusionUpdater(
    std::unique_ptr<DiffusionFormulationType> formulation_ptr,
    std::shared_ptr<StamperType> stamper_ptr,
    std::unordered_set<problem::Boundary> reflective_boundaries)
    : FixedUpdater<dim>(stamper_ptr),
      formulation_ptr_(std::move(formulation_ptr)),
      stamper_ptr_(stamper_ptr),
      reflective_boundaries_(reflective_boundaries) {
  AssertThrow(formulation_ptr_ != nullptr,
              dealii::ExcMessage("Error in constructor of DiffusionUpdater, "
                                 "formulation pointer passed is null"))
  AssertThrow(stamper_ptr_ != nullptr,
              dealii::ExcMessage("Error in constructor of DiffusionUpdater, "
                                 "stamper pointer passed is null"))
  this->set_description("diffusion formulation updater",
                        utility::DefaultImplementation(true));

  if (!reflective_boundaries_.empty()) {
    this->set_description(this->description() + " (reflective BCs)",
                          utility::DefaultImplementation(true));
  }
}

template<int dim>
auto DiffusionUpdater<dim>::SetUpFixedFunctions(system::System& /*to_update*/,
                                                system::EnergyGroup group,
                                                quadrature::QuadraturePointIndex /*index*/) -> void {
  this->fixed_matrix_functions_ = {};
  this->fixed_vector_functions_ = {};
  this->fixed_matrix_boundary_functions_ = {};
  this->fixed_vector_boundary_functions_ = {};

  const auto streaming_term_function = [&, group](formulation::FullMatrix& cell_matrix, const CellPtr& cell_ptr) -> void {
    formulation_ptr_->FillCellStreamingTerm(cell_matrix, cell_ptr, group.get()); };
  const auto collision_term_function = [&, group](formulation::FullMatrix& cell_matrix, const CellPtr& cell_ptr) -> void {
    formulation_ptr_->FillCellCollisionTerm(cell_matrix, cell_ptr, group.get()); };
  this->fixed_matrix_functions_.push_back(streaming_term_function);
  this->fixed_matrix_functions_.push_back(collision_term_function);

  auto fixed_term_function = [&, group](formulation::Vector& cell_vector, const CellPtr& cell_ptr) -> void {
    formulation_ptr_->FillCellFixedSource(cell_vector, cell_ptr, group.get()); };
  this->fixed_vector_functions_.push_back(fixed_term_function);
  if (this->rhs_constant_vector_ptr_ != nullptr) {
    auto constant_term_function = [=](formulation::Vector& cell_vector, const CellPtr& cell_ptr) -> void {
      formulation_ptr_->FillCellConstantTerm(cell_vector, cell_ptr, *this->rhs_constant_vector_ptr_); };
    this->fixed_vector_functions_.push_back(constant_term_function);
  }

  auto boundary_function = [&](formulation::FullMatrix& cell_matrix, const domain::FaceIndex face_index,
                               const CellPtr& cell_ptr) -> void {
    using DiffusionBoundaryType = typename formulation::scalar::DiffusionI<dim>::BoundaryType;

    DiffusionBoundaryType boundary_type = DiffusionBoundaryType::kVacuum;

    if (cell_ptr->at_boundary()) {
      problem::Boundary boundary = static_cast<problem::Boundary>(cell_ptr->face(face_index.get())->boundary_id());
      if (reflective_boundaries_.count(boundary) == 1)
        boundary_type = DiffusionBoundaryType::kReflective;
      formulation_ptr_->FillBoundaryTerm(cell_matrix, cell_ptr,face_index.get(), boundary_type);
    }
  };
  this->fixed_matrix_boundary_functions_.push_back(boundary_function);
}

template<int dim>
void DiffusionUpdater<dim>::UpdateScatteringSource(system::System &to_update, const system::EnergyGroup energy_group,
                                                   quadrature::QuadraturePointIndex /*index*/) {
  using system::terms::VariableLinearTerms;
  using CellPtr = typename domain::CellPtr<dim>;
  const int group = energy_group.get();
  auto scattering_source_ptr = to_update.right_hand_side_ptr_->GetVariableTermPtr({group, 0}, VariableLinearTerms::kScatteringSource);
  *scattering_source_ptr = 0;
  const auto& current_moments = to_update.current_moments->moments();
  auto scattering_source_function = [&](formulation::Vector& cell_vector, const CellPtr& cell_ptr) -> void {
        formulation_ptr_->FillCellScatteringSource(cell_vector, cell_ptr, group, current_moments);
  };
  stamper_ptr_->StampVector(*scattering_source_ptr, scattering_source_function);
}
template<int dim>
void DiffusionUpdater<dim>::UpdateFissionSource(system::System &to_update,system::EnergyGroup energy_group,
    quadrature::QuadraturePointIndex /*index*/) {
  using system::terms::VariableLinearTerms;
  using CellPtr = typename domain::CellPtr<dim>;
  const int group = energy_group.get();
  auto fission_source_ptr = to_update.right_hand_side_ptr_->GetVariableTermPtr({group, 0}, VariableLinearTerms::kFissionSource);
  *fission_source_ptr = 0;
  const auto& current_moments = to_update.current_moments->moments();
  const auto& in_group_moment = current_moments.at({group, 0, 0});
  auto fission_source_function = [&](formulation::Vector& cell_vector, const CellPtr& cell_ptr) -> void {
    formulation_ptr_->FillCellFissionSource(cell_vector, cell_ptr, group, to_update.k_effective.value(),
                                            in_group_moment, current_moments);
  };
  stamper_ptr_->StampVector(*fission_source_ptr, fission_source_function);
}
template<int dim>
void DiffusionUpdater<dim>::UpdateFixedSource(
    system::System &to_update,
    system::EnergyGroup energy_group,
    quadrature::QuadraturePointIndex /*index*/) {
  int group = energy_group.get();
  auto fixed_source_ptr =
      to_update.right_hand_side_ptr_->GetFixedTermPtr({group, 0});
  *fixed_source_ptr = 0;
  auto fixed_source_function =
      [&](formulation::Vector& cell_vector,
          const domain::CellPtr<dim> &cell_ptr) -> void {
        formulation_ptr_->FillCellFixedSource(cell_vector,
                                              cell_ptr, group);
      };
  stamper_ptr_->StampVector(*fixed_source_ptr, fixed_source_function);
}

template class DiffusionUpdater<1>;
template class DiffusionUpdater<2>;
template class DiffusionUpdater<3>;

} // namespace updater

} // namespace formulation

} // namespace bart
<|endoftext|>


<commit_before>/*
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.

Author: Leonardo de Moura
*/
#include "util/lazy_list_fn.h"
#include "util/flet.h"
#include "kernel/instantiate.h"
#include "kernel/abstract.h"
#include "library/unifier.h"
#include "library/reducible.h"
#include "library/metavar_closure.h"
#include "library/error_handling/error_handling.h"
#include "frontends/lean/util.h"
#include "frontends/lean/class.h"
#include "frontends/lean/tactic_hint.h"
#include "frontends/lean/local_context.h"
#include "frontends/lean/choice_iterator.h"

namespace lean {
/** \brief Context for handling placeholder metavariable choice constraint */
struct placeholder_context {
    io_state         m_ios;
    name_generator   m_ngen;
    type_checker_ptr m_tc;
    local_context    m_ctx;
    bool             m_relax;
    bool             m_use_local_instances;
    placeholder_context(environment const & env, io_state const & ios, local_context const & ctx,
                        name const & prefix, bool relax, bool use_local_instances):
        m_ios(ios),
        m_ngen(prefix),
        m_tc(mk_type_checker(env, m_ngen.mk_child(), relax)),
        m_ctx(ctx),
        m_relax(relax),
        m_use_local_instances(use_local_instances) {
    }

    environment const & env() const { return m_tc->env(); }
    io_state const & ios() const { return m_ios; }
    bool use_local_instances() const { return m_use_local_instances; }
    type_checker & tc() const { return *m_tc; }
};

pair<expr, constraint> mk_placeholder_elaborator(std::shared_ptr<placeholder_context> const & C,
                                                 bool is_strict, optional<expr> const & type, tag g);

/** \brief Whenever the elaborator finds a placeholder '_' or introduces an
    implicit argument, it creates a metavariable \c ?m. It also creates a
    delayed choice constraint (?m in fn).

    The function \c fn produces a stream of alternative solutions for ?m.
    In this case, \c fn will do the following:
    1) if the elaborated type of ?m is a 'class' C, then the stream will start with
         a) all local instances of class C (if elaborator.local_instances == true)
         b) solutions produced by tactic_hints for class C

    2) if the elaborated type of ?m is not a class, then the stream will only contain
       the solutions produced by tactic_hints.

    The unifier only process delayed choice constraints when there are no other kind
    of constraint to be processed.

    This is a helper class for implementing this choice function.
*/
struct placeholder_elaborator : public choice_iterator {
    std::shared_ptr<placeholder_context> m_C;
    expr                    m_meta;
    // elaborated type of the metavariable
    expr                    m_meta_type;
    // local instances that should also be included in the
    // class-instance resolution.
    // This information is retrieved from the local context
    list<expr>              m_local_instances;
    // global declaration names that are class instances.
    // This information is retrieved using #get_class_instances.
    list<name>              m_instances;
    // Tactic hints for the class
    list<tactic_hint_entry> m_tactics;
    // result produce by last executed tactic.
    proof_state_seq         m_tactic_result;
    justification           m_jst;

    placeholder_elaborator(std::shared_ptr<placeholder_context> const & C,
                           expr const & meta, expr const & meta_type,
                           list<expr> const & local_insts, list<name> const & instances,
                           list<tactic_hint_entry> const & tacs,
                           justification const & j, bool ignore_failure):
        choice_iterator(ignore_failure), m_C(C),
        m_meta(meta), m_meta_type(meta_type),
        m_local_instances(local_insts), m_instances(instances),
        m_tactics(tacs),
        m_jst(j) {
    }

    constraints mk_constraints(constraint const & c, buffer<constraint> const & cs) {
        return cons(c, to_list(cs.begin(), cs.end()));
    }

    optional<constraints> try_instance(expr const & inst, expr const & inst_type) {
        type_checker & tc     = m_C->tc();
        name_generator & ngen = m_C->m_ngen;
        tag g                 = inst.get_tag();
        local_context & ctx   = m_C->m_ctx;
        try {
            flet<local_context> scope(ctx, ctx);
            buffer<expr> locals;
            expr meta_type = m_meta_type;
            while (true) {
                meta_type = tc.whnf(meta_type).first;
                if (!is_pi(meta_type))
                    break;
                expr local  = mk_local(ngen.next(), binding_name(meta_type),
                                       binding_domain(meta_type), binding_info(meta_type));
                ctx.add_local(local);
                locals.push_back(local);
                meta_type = instantiate(binding_body(meta_type), local);
            }
            expr type  = inst_type;
            expr r     = inst;
            buffer<constraint> cs;
            while (true) {
                type = tc.whnf(type).first;
                if (!is_pi(type))
                    break;
                bool is_strict = true;
                pair<expr, constraint> ac = mk_placeholder_elaborator(m_C, is_strict,
                                                                      some_expr(binding_domain(type)), g);
                expr arg = ac.first;
                cs.push_back(ac.second);
                r    = mk_app(r, arg).set_tag(g);
                type = instantiate(binding_body(type), arg);
            }
            r = Fun(locals, r);
            bool relax   = m_C->m_relax;
            constraint c = mk_eq_cnstr(m_meta, r, m_jst, relax);
            return optional<constraints>(mk_constraints(c, cs));
        } catch (exception &) {
            return optional<constraints>();
        }
    }

    optional<constraints> try_instance(name const & inst) {
        environment const & env = m_C->env();
        if (auto decl = env.find(inst)) {
            name_generator & ngen = m_C->m_ngen;
            buffer<level> ls_buffer;
            unsigned num_univ_ps = length(decl->get_univ_params());
            for (unsigned i = 0; i < num_univ_ps; i++)
                ls_buffer.push_back(mk_meta_univ(ngen.next()));
            levels ls = to_list(ls_buffer.begin(), ls_buffer.end());
            expr inst_cnst = copy_tag(m_meta, mk_constant(inst, ls));
            expr inst_type = instantiate_type_univ_params(*decl, ls);
            return try_instance(inst_cnst, inst_type);
        } else {
            return optional<constraints>();
        }
    }

    optional<constraints> get_next_tactic_result() {
        while (auto next = m_tactic_result.pull()) {
            m_tactic_result = next->second;
            if (!empty(next->first.get_goals()))
                continue; // has unsolved goals
            substitution subst = next->first.get_subst();
            expr const & mvar = get_app_fn(m_meta);
            bool relax        = m_C->m_relax;
            constraints cs    = metavar_closure(m_meta_type).mk_constraints(subst, m_jst, relax);
            constraint  c     = mk_eq_cnstr(mvar, subst.instantiate(mvar), m_jst, relax);
            return some(cons(c, cs));
        }
        return optional<constraints>();
    }

    virtual optional<constraints> next() {
        while (!empty(m_local_instances)) {
            expr inst         = head(m_local_instances);
            m_local_instances = tail(m_local_instances);
            if (!is_local(inst))
                continue;
            if (auto r = try_instance(inst, mlocal_type(inst)))
                return r;
        }
        while (!empty(m_instances)) {
            name inst   = head(m_instances);
            m_instances = tail(m_instances);
            if (auto cs = try_instance(inst))
                return cs;
        }
        if (auto cs = get_next_tactic_result())
            return cs;
        while (!empty(m_tactics)) {
            tactic const & tac = head(m_tactics).get_tactic();
            m_tactics          = tail(m_tactics);
            proof_state ps(goals(goal(m_meta, m_meta_type)), substitution(), m_C->m_ngen.mk_child());
            try {
                m_tactic_result    = tac(m_C->env(), m_C->ios(), ps);
                if (auto cs = get_next_tactic_result())
                    return cs;
            } catch (exception &) {}
        }
        return optional<constraints>();
    }
};

constraint mk_placeholder_cnstr(std::shared_ptr<placeholder_context> const & C, expr const & m, bool is_strict) {
    environment const & env = C->env();
    justification j         = mk_failed_to_synthesize_jst(env, m);
    auto choice_fn = [=](expr const & meta, expr const & meta_type, substitution const & s,
                         name_generator const & /* ngen */) {
        expr const & mvar = get_app_fn(meta);
        if (auto cls_name_it = is_ext_class(C->tc(), meta_type)) {
            name cls_name = *cls_name_it;
            list<expr> const & ctx = C->m_ctx.get_data();
            list<expr> local_insts;
            if (C->use_local_instances())
                local_insts = get_local_instances(C->tc(), ctx, cls_name);
            list<name>  insts = get_class_instances(env, cls_name);
            list<tactic_hint_entry> tacs;
            if (!s.is_assigned(mvar))
                tacs = get_tactic_hints(env, cls_name);
            if (empty(local_insts) && empty(insts) && empty(tacs))
                return lazy_list<constraints>(); // nothing to be done
            // we are always strict with placeholders associated with classes
            bool ignore_failure = false;
            return choose(std::make_shared<placeholder_elaborator>(C, meta, meta_type, local_insts, insts, tacs,
                                                                   j, ignore_failure));
        } else if (s.is_assigned(mvar)) {
            // if the metavariable is assigned and it is not a class, then we just ignore it, and return
            // the an empty set of constraints.
            return lazy_list<constraints>(constraints());
        } else {
            list<tactic_hint_entry> tacs = get_tactic_hints(env);
            bool ignore_failure = !is_strict;
            return choose(std::make_shared<placeholder_elaborator>(C, meta, meta_type, list<expr>(), list<name>(),
                                                                   tacs, j, ignore_failure));
        }
    };
    bool owner      = false;
    bool relax      = C->m_relax;
    return mk_choice_cnstr(m, choice_fn, to_delay_factor(cnstr_group::ClassInstance),
                           owner, j, relax);
}

pair<expr, constraint> mk_placeholder_elaborator(std::shared_ptr<placeholder_context> const & C,
                                                 bool is_strict, optional<expr> const & type, tag g) {
    expr m       = C->m_ctx.mk_meta(C->m_ngen, type, g);
    constraint c = mk_placeholder_cnstr(C, m, is_strict);
    return mk_pair(m, c);
}

constraint mk_placeholder_root_cnstr(std::shared_ptr<placeholder_context> const & C, expr const & m, bool is_strict,
                                     unifier_config const & cfg, unsigned delay_factor) {
    environment const & env = C->env();
    justification j         = mk_failed_to_synthesize_jst(env, m);
    auto choice_fn = [=](expr const & meta, expr const & meta_type, substitution const & s,
                         name_generator const & ngen) {
        if (has_expr_metavar(meta_type)) {
            if (delay_factor < to_delay_factor(cnstr_group::ClassInstance)) {
                constraint delayed_c = mk_placeholder_root_cnstr(C, m, is_strict, cfg, delay_factor+1);
                return lazy_list<constraints>(constraints(delayed_c));
            }
        }
        expr const & mvar = get_app_fn(meta);
        if (!is_ext_class(C->tc(), meta_type) && s.is_assigned(mvar)) {
            // see mk_placeholder_cnstr
            return lazy_list<constraints>(constraints());
        }
        pair<expr, justification> mj = update_meta(meta, s);
        expr new_meta       = mj.first;
        justification new_j = mj.second;
        constraint c = mk_placeholder_cnstr(C, new_meta, is_strict);
        unifier_config new_cfg(cfg);
        new_cfg.m_discard        = false;
        new_cfg.m_use_exceptions = false;
        unify_result_seq seq = unify(env, 1, &c, ngen, new_cfg);
        return map2<constraints>(seq, [=](pair<substitution, constraints> const & p) {
                substitution new_s     = p.first;
                if (!new_s.is_expr_assigned(mlocal_name(get_app_fn(new_meta))))
                    constraints();
                constraints  postponed = map(p.second,
                                             [&](constraint const & c) {
                                                 // we erase internal justifications
                                                 return update_justification(c, new_j);
                                             });
                metavar_closure cls(new_meta);
                cls.add(meta_type);
                bool relax     = C->m_relax;
                constraints cs = cls.mk_constraints(new_s, new_j, relax);
                return append(cs, postponed);
            });
    };
    bool owner = false;
    bool relax = C->m_relax;
    return mk_choice_cnstr(m, choice_fn, delay_factor, owner, j, relax);
}

/** \brief Create a metavariable, and attach choice constraint for generating
    solutions using class-instances and tactic-hints.
*/
pair<expr, constraint> mk_placeholder_elaborator(
    environment const & env, io_state const & ios, local_context const & ctx,
    name const & prefix, bool relax, bool use_local_instances,
    bool is_strict, optional<expr> const & type, tag g, unifier_config const & cfg) {
    auto C       = std::make_shared<placeholder_context>(env, ios, ctx, prefix, relax, use_local_instances);
    expr m       = C->m_ctx.mk_meta(C->m_ngen, type, g);
    constraint c = mk_placeholder_root_cnstr(C, m, is_strict, cfg, to_delay_factor(cnstr_group::Basic));
    return mk_pair(m, c);
}
}
<commit_msg>fix(frontends/lean/placeholder_elaborator): missing 'return'<commit_after>/*
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.

Author: Leonardo de Moura
*/
#include "util/lazy_list_fn.h"
#include "util/flet.h"
#include "kernel/instantiate.h"
#include "kernel/abstract.h"
#include "library/unifier.h"
#include "library/reducible.h"
#include "library/metavar_closure.h"
#include "library/error_handling/error_handling.h"
#include "frontends/lean/util.h"
#include "frontends/lean/class.h"
#include "frontends/lean/tactic_hint.h"
#include "frontends/lean/local_context.h"
#include "frontends/lean/choice_iterator.h"

namespace lean {
/** \brief Context for handling placeholder metavariable choice constraint */
struct placeholder_context {
    io_state         m_ios;
    name_generator   m_ngen;
    type_checker_ptr m_tc;
    local_context    m_ctx;
    bool             m_relax;
    bool             m_use_local_instances;
    placeholder_context(environment const & env, io_state const & ios, local_context const & ctx,
                        name const & prefix, bool relax, bool use_local_instances):
        m_ios(ios),
        m_ngen(prefix),
        m_tc(mk_type_checker(env, m_ngen.mk_child(), relax)),
        m_ctx(ctx),
        m_relax(relax),
        m_use_local_instances(use_local_instances) {
    }

    environment const & env() const { return m_tc->env(); }
    io_state const & ios() const { return m_ios; }
    bool use_local_instances() const { return m_use_local_instances; }
    type_checker & tc() const { return *m_tc; }
};

pair<expr, constraint> mk_placeholder_elaborator(std::shared_ptr<placeholder_context> const & C,
                                                 bool is_strict, optional<expr> const & type, tag g);

/** \brief Whenever the elaborator finds a placeholder '_' or introduces an
    implicit argument, it creates a metavariable \c ?m. It also creates a
    delayed choice constraint (?m in fn).

    The function \c fn produces a stream of alternative solutions for ?m.
    In this case, \c fn will do the following:
    1) if the elaborated type of ?m is a 'class' C, then the stream will start with
         a) all local instances of class C (if elaborator.local_instances == true)
         b) solutions produced by tactic_hints for class C

    2) if the elaborated type of ?m is not a class, then the stream will only contain
       the solutions produced by tactic_hints.

    The unifier only process delayed choice constraints when there are no other kind
    of constraint to be processed.

    This is a helper class for implementing this choice function.
*/
struct placeholder_elaborator : public choice_iterator {
    std::shared_ptr<placeholder_context> m_C;
    expr                    m_meta;
    // elaborated type of the metavariable
    expr                    m_meta_type;
    // local instances that should also be included in the
    // class-instance resolution.
    // This information is retrieved from the local context
    list<expr>              m_local_instances;
    // global declaration names that are class instances.
    // This information is retrieved using #get_class_instances.
    list<name>              m_instances;
    // Tactic hints for the class
    list<tactic_hint_entry> m_tactics;
    // result produce by last executed tactic.
    proof_state_seq         m_tactic_result;
    justification           m_jst;

    placeholder_elaborator(std::shared_ptr<placeholder_context> const & C,
                           expr const & meta, expr const & meta_type,
                           list<expr> const & local_insts, list<name> const & instances,
                           list<tactic_hint_entry> const & tacs,
                           justification const & j, bool ignore_failure):
        choice_iterator(ignore_failure), m_C(C),
        m_meta(meta), m_meta_type(meta_type),
        m_local_instances(local_insts), m_instances(instances),
        m_tactics(tacs),
        m_jst(j) {
    }

    constraints mk_constraints(constraint const & c, buffer<constraint> const & cs) {
        return cons(c, to_list(cs.begin(), cs.end()));
    }

    optional<constraints> try_instance(expr const & inst, expr const & inst_type) {
        type_checker & tc     = m_C->tc();
        name_generator & ngen = m_C->m_ngen;
        tag g                 = inst.get_tag();
        local_context & ctx   = m_C->m_ctx;
        try {
            flet<local_context> scope(ctx, ctx);
            buffer<expr> locals;
            expr meta_type = m_meta_type;
            while (true) {
                meta_type = tc.whnf(meta_type).first;
                if (!is_pi(meta_type))
                    break;
                expr local  = mk_local(ngen.next(), binding_name(meta_type),
                                       binding_domain(meta_type), binding_info(meta_type));
                ctx.add_local(local);
                locals.push_back(local);
                meta_type = instantiate(binding_body(meta_type), local);
            }
            expr type  = inst_type;
            expr r     = inst;
            buffer<constraint> cs;
            while (true) {
                type = tc.whnf(type).first;
                if (!is_pi(type))
                    break;
                bool is_strict = true;
                pair<expr, constraint> ac = mk_placeholder_elaborator(m_C, is_strict,
                                                                      some_expr(binding_domain(type)), g);
                expr arg = ac.first;
                cs.push_back(ac.second);
                r    = mk_app(r, arg).set_tag(g);
                type = instantiate(binding_body(type), arg);
            }
            r = Fun(locals, r);
            bool relax   = m_C->m_relax;
            constraint c = mk_eq_cnstr(m_meta, r, m_jst, relax);
            return optional<constraints>(mk_constraints(c, cs));
        } catch (exception &) {
            return optional<constraints>();
        }
    }

    optional<constraints> try_instance(name const & inst) {
        environment const & env = m_C->env();
        if (auto decl = env.find(inst)) {
            name_generator & ngen = m_C->m_ngen;
            buffer<level> ls_buffer;
            unsigned num_univ_ps = length(decl->get_univ_params());
            for (unsigned i = 0; i < num_univ_ps; i++)
                ls_buffer.push_back(mk_meta_univ(ngen.next()));
            levels ls = to_list(ls_buffer.begin(), ls_buffer.end());
            expr inst_cnst = copy_tag(m_meta, mk_constant(inst, ls));
            expr inst_type = instantiate_type_univ_params(*decl, ls);
            return try_instance(inst_cnst, inst_type);
        } else {
            return optional<constraints>();
        }
    }

    optional<constraints> get_next_tactic_result() {
        while (auto next = m_tactic_result.pull()) {
            m_tactic_result = next->second;
            if (!empty(next->first.get_goals()))
                continue; // has unsolved goals
            substitution subst = next->first.get_subst();
            expr const & mvar = get_app_fn(m_meta);
            bool relax        = m_C->m_relax;
            constraints cs    = metavar_closure(m_meta_type).mk_constraints(subst, m_jst, relax);
            constraint  c     = mk_eq_cnstr(mvar, subst.instantiate(mvar), m_jst, relax);
            return some(cons(c, cs));
        }
        return optional<constraints>();
    }

    virtual optional<constraints> next() {
        while (!empty(m_local_instances)) {
            expr inst         = head(m_local_instances);
            m_local_instances = tail(m_local_instances);
            if (!is_local(inst))
                continue;
            if (auto r = try_instance(inst, mlocal_type(inst)))
                return r;
        }
        while (!empty(m_instances)) {
            name inst   = head(m_instances);
            m_instances = tail(m_instances);
            if (auto cs = try_instance(inst))
                return cs;
        }
        if (auto cs = get_next_tactic_result())
            return cs;
        while (!empty(m_tactics)) {
            tactic const & tac = head(m_tactics).get_tactic();
            m_tactics          = tail(m_tactics);
            proof_state ps(goals(goal(m_meta, m_meta_type)), substitution(), m_C->m_ngen.mk_child());
            try {
                m_tactic_result    = tac(m_C->env(), m_C->ios(), ps);
                if (auto cs = get_next_tactic_result())
                    return cs;
            } catch (exception &) {}
        }
        return optional<constraints>();
    }
};

constraint mk_placeholder_cnstr(std::shared_ptr<placeholder_context> const & C, expr const & m, bool is_strict) {
    environment const & env = C->env();
    justification j         = mk_failed_to_synthesize_jst(env, m);
    auto choice_fn = [=](expr const & meta, expr const & meta_type, substitution const & s,
                         name_generator const & /* ngen */) {
        expr const & mvar = get_app_fn(meta);
        if (auto cls_name_it = is_ext_class(C->tc(), meta_type)) {
            name cls_name = *cls_name_it;
            list<expr> const & ctx = C->m_ctx.get_data();
            list<expr> local_insts;
            if (C->use_local_instances())
                local_insts = get_local_instances(C->tc(), ctx, cls_name);
            list<name>  insts = get_class_instances(env, cls_name);
            list<tactic_hint_entry> tacs;
            if (!s.is_assigned(mvar))
                tacs = get_tactic_hints(env, cls_name);
            if (empty(local_insts) && empty(insts) && empty(tacs))
                return lazy_list<constraints>(); // nothing to be done
            // we are always strict with placeholders associated with classes
            bool ignore_failure = false;
            return choose(std::make_shared<placeholder_elaborator>(C, meta, meta_type, local_insts, insts, tacs,
                                                                   j, ignore_failure));
        } else if (s.is_assigned(mvar)) {
            // if the metavariable is assigned and it is not a class, then we just ignore it, and return
            // the an empty set of constraints.
            return lazy_list<constraints>(constraints());
        } else {
            list<tactic_hint_entry> tacs = get_tactic_hints(env);
            bool ignore_failure = !is_strict;
            return choose(std::make_shared<placeholder_elaborator>(C, meta, meta_type, list<expr>(), list<name>(),
                                                                   tacs, j, ignore_failure));
        }
    };
    bool owner      = false;
    bool relax      = C->m_relax;
    return mk_choice_cnstr(m, choice_fn, to_delay_factor(cnstr_group::ClassInstance),
                           owner, j, relax);
}

pair<expr, constraint> mk_placeholder_elaborator(std::shared_ptr<placeholder_context> const & C,
                                                 bool is_strict, optional<expr> const & type, tag g) {
    expr m       = C->m_ctx.mk_meta(C->m_ngen, type, g);
    constraint c = mk_placeholder_cnstr(C, m, is_strict);
    return mk_pair(m, c);
}

constraint mk_placeholder_root_cnstr(std::shared_ptr<placeholder_context> const & C, expr const & m, bool is_strict,
                                     unifier_config const & cfg, unsigned delay_factor) {
    environment const & env = C->env();
    justification j         = mk_failed_to_synthesize_jst(env, m);
    auto choice_fn = [=](expr const & meta, expr const & meta_type, substitution const & s,
                         name_generator const & ngen) {
        if (has_expr_metavar(meta_type)) {
            if (delay_factor < to_delay_factor(cnstr_group::ClassInstance)) {
                constraint delayed_c = mk_placeholder_root_cnstr(C, m, is_strict, cfg, delay_factor+1);
                return lazy_list<constraints>(constraints(delayed_c));
            }
        }
        expr const & mvar = get_app_fn(meta);
        if (!is_ext_class(C->tc(), meta_type) && s.is_assigned(mvar)) {
            // see mk_placeholder_cnstr
            return lazy_list<constraints>(constraints());
        }
        pair<expr, justification> mj = update_meta(meta, s);
        expr new_meta       = mj.first;
        justification new_j = mj.second;
        constraint c = mk_placeholder_cnstr(C, new_meta, is_strict);
        unifier_config new_cfg(cfg);
        new_cfg.m_discard        = false;
        new_cfg.m_use_exceptions = false;
        unify_result_seq seq = unify(env, 1, &c, ngen, new_cfg);
        return map2<constraints>(seq, [=](pair<substitution, constraints> const & p) {
                substitution new_s     = p.first;
                if (!new_s.is_expr_assigned(mlocal_name(get_app_fn(new_meta))))
                    return constraints();
                constraints  postponed = map(p.second,
                                             [&](constraint const & c) {
                                                 // we erase internal justifications
                                                 return update_justification(c, new_j);
                                             });
                metavar_closure cls(new_meta);
                cls.add(meta_type);
                bool relax     = C->m_relax;
                constraints cs = cls.mk_constraints(new_s, new_j, relax);
                return append(cs, postponed);
            });
    };
    bool owner = false;
    bool relax = C->m_relax;
    return mk_choice_cnstr(m, choice_fn, delay_factor, owner, j, relax);
}

/** \brief Create a metavariable, and attach choice constraint for generating
    solutions using class-instances and tactic-hints.
*/
pair<expr, constraint> mk_placeholder_elaborator(
    environment const & env, io_state const & ios, local_context const & ctx,
    name const & prefix, bool relax, bool use_local_instances,
    bool is_strict, optional<expr> const & type, tag g, unifier_config const & cfg) {
    auto C       = std::make_shared<placeholder_context>(env, ios, ctx, prefix, relax, use_local_instances);
    expr m       = C->m_ctx.mk_meta(C->m_ngen, type, g);
    constraint c = mk_placeholder_root_cnstr(C, m, is_strict, cfg, to_delay_factor(cnstr_group::Basic));
    return mk_pair(m, c);
}
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/utils/imageProcs/p9_tor.H $               */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
#ifndef _P9_TOR_H_
#define _P9_TOR_H_

#include "p9_ring_identification.H"
#include "p9_ringId.H"

namespace P9_TOR
{

#define NUM_RING_IDS              P9_NUM_RINGS

typedef struct
{
    uint32_t sizeOfThis;
    uint16_t sizeOfCmsk;
    uint16_t sizeOfMeta; // Exact size of meta data. Arbitrary size. Not null terminated.
} RingLayout_t;

//
// Temporary define until in TOR header by Giri.
//
//
// Temporary define until in TOR header by Giri.
//
typedef struct
{
    uint32_t TorNumDdLevels;
    uint32_t reserved;
} TorNumDdLevels_t;

typedef struct
{
    uint32_t TorDdLevelAndOffset;
    uint32_t TorDdBlockSize;
} TorDdLevelBlock_t;

typedef struct
{
    uint32_t TorPpeTypeOffset;
    uint32_t TorPpeBlockSize;
} TorPpeBlock_t;

#define IMGBUILD_TGR_RING_FOUND                        0
#define IMGBUILD_TGR_RING_BLOCKS_FOUND                 0
#define IMGBUILD_TGR_RING_NOT_FOUND                    1  // Ring is not found in HW image.
#define IMGBUILD_TGR_INVALID_RING_ID                   2  // Ring is invalid or mismatch.
#define IMGBUILD_TGR_AMBIGUOUS_API_PARMS               3  // Ring search in HW iamge got ambiguous condition.
#define IMGBUILD_TGR_SECTION_NOT_FOUND                 4
#define IMGBUILD_TGR_DD_LVL_INFO_NOT_FOUND             5
#define IMGBUILD_TGR_OP_BUFFER_INVALID                 6
#define IMGBUILD_TGR_OP_BUFFER_SIZE_EXCEEDED           7
#define IMGBUILD_INVALID_INSTANCEID                    8
#define IMGBUILD_TGR_IMAGE_DOES_NOT_SUPPORT_CME       10
#define IMGBUILD_TGR_IMAGE_DOES_NOT_SUPPORT_SGPE      11
#define IMGBUILD_TGR_IMAGE_DOES_NOT_SUPPORT_DD_LEVEL  12
#define IMGBUILD_TGR_IMAGE_DOES_NOT_SUPPORT_PPE_LEVEL 13

extern const char* ringVariantName[];
extern const char* ppeTypeName[];

typedef enum
RingBlockType   // Different options to extract data using tor_get_ring API
{
    SINGLE_RING      = 0x00,
    DD_LEVEL_RINGS   = 0x01,
    PPE_LEVEL_RINGS  = 0x02,
    CPLT_LEVEL_RINGS = 0x03
} RingBlockType_t;

typedef enum RingType      // Different type of Rings
{
    COMMON   = 0x00,
    INSTANCE = 0x01,
    ALLRING  = 0x02
} RingType_t;

typedef enum RingVariant   // Base variables
{
    BASE     = 0x00,
    CC       = 0x01,
    RL       = 0x02,
    OVERRIDE = 0x03,
    OVERLAY  = 0x04,
    NUM_RING_VARIANTS = 0x05,
    NOT_VALID = 0xff
} RingVariant_t;

//
// PPE types
//
typedef enum PpeType
{
    SBE           = 0x00,     // Ppe type partition in Ringsection
    CME           = 0x01,
    SGPE          = 0x02,
    NUM_PPE_TYPES = 0x03
} PpeType_t;

typedef enum RingSectionId
{
    SECTION_RING    = 0x00,    //.ring section ID
    SECTION_OVRD    = 0x01,    //.Override section ID
    SECTION_OVRL    = 0x02     //.Overlay section ID
} RingSectionId_t;

typedef enum SbeTorId
{
    PERV_CPLT = 0,
    N0_CPLT =   1,
    N1_CPLT =   2,
    N2_CPLT =   3,
    N3_CPLT =   4,
    XB_CPLT =   5,
    MC_CPLT =   6,
    OB0_CPLT =  7,
    OB1_CPLT =  8,
    OB2_CPLT =  9,
    OB3_CPLT =  10,
    PCI0_CPLT = 11,
    PCI1_CPLT = 12,
    PCI2_CPLT = 13,
    EQ_CPLT   = 14,
    EC_CPLT   = 15,
    SBE_NOOF_CHIPLETS =   16
} SbeTorId_t;
typedef enum CmeTorId
{
    CME0_CPLT    = 0,
    CME1_CPLT    = 1,
    CME2_CPLT    = 2,
    CME3_CPLT    = 3,
    CME4_CPLT    = 4,
    CME5_CPLT    = 5,
    CME6_CPLT    = 6,
    CME7_CPLT    = 7,
    CME8_CPLT    = 8,
    CME9_CPLT    = 9,
    CME10_CPLT   = 10,
    CME11_CPLT   = 11,
    CME_NOOF_CHIPLETS = 12
} CmeTorId_t;
///
/// ****************************************************************************
/// Function declares.
/// ****************************************************************************
///

int get_ring_from_sbe_image ( void*
                              i_ringSectionPtr, // Image pointer
                              uint64_t        i_magic,          // Image Magic Number
                              RingID          i_ringId,         // Unique ring ID
                              uint16_t        i_ddLevel,        // DD level details
                              RingType_t&     io_RingType,      // 0: Common 1: Instance
                              RingVariant_t   i_RingVariant,    // Base, cache contained, Risk level,
                              // Override and Overlay
                              uint8_t&        io_instanceId,    // required Instance
                              RingBlockType_t RingBlockType,    // 0: single ring,  1: ddLevel block
                              void**          io_ringBlockPtr,  // RS4 Container data or block data
                              uint32_t&       io_ringBlockSize, // size of data copied into ring block pointer
                              char*           o_ringName,       // Name of ring
                              uint32_t        dbgl);            // Debug option

int get_ring_from_sgpe_image ( void*
                               i_ringSectionPtr, // Image pointer
                               RingID          i_ringId,         // Unique ring ID
                               uint16_t        i_ddLevel,        // DD level details
                               RingType_t&      io_RingType,       // 0: Common 1: Instance
                               RingVariant_t   i_RingVariant,    // Base, cache contained, Risk level,
                               // Override and Overlay
                               uint8_t&         io_instanceId,    // required Instance
                               RingBlockType_t RingBlockType,    // 0: single ring,  1: ddLevel block
                               void**          io_ringBlockPtr,   // RS4 Container data or block data
                               uint32_t&       io_ringBlockSize, // size of data copied into ring block pointer
                               char*           o_ringName,       // Name of ring
                               uint32_t        dbgl);            // Debug option

int get_ring_from_cme_image ( void*           i_ringSectionPtr, // Image pointer
                              RingID          i_ringId,         // Unique ring ID
                              uint16_t        i_ddLevel,        // DD level details
                              RingType_t&      io_RingType,       // 0: Common 1: Instance
                              RingVariant_t   i_RingVariant,    // Base, cache contained, Risk level,
                              // Override and Overlay
                              uint8_t&        io_instanceId,    // required Instance
                              RingBlockType_t RingBlockType,    // 0: single ring,  1: ddLevel block
                              void**          io_ringBlockPtr,   // RS4 Container data or block data
                              uint32_t&       io_ringBlockSize, // size of data copied into ring block pointer
                              char*           o_ringName,       // Name of ring
                              uint32_t        dbgl);            // Debug option

int tor_get_ring(  void*
                   i_ringSectionPtr, // Ring address Ptr any of .rings, .overrides and .overlays.
                   uint64_t        i_magic,          // Image Magic Number
                   RingID          i_ringId,         // Unique ring ID
                   uint16_t        i_ddLevel,        // DD level info
                   PpeType_t       i_PpeType,        // PPE type : SBE, CME, etc
                   RingType_t&      io_RingType,     // 0: Common 1: Instance
                   RingVariant_t   i_RingVariant,    // Base, Cache etc
                   uint8_t&        io_instanceId,     // chiplet instance ID
                   RingBlockType_t i_RingBlockType,  // 0: single ring,  1: ring block
                   void**          io_ringBlockPtr,  // Addr of ring buffer
                   uint32_t&       io_ringBlockSize, // size of ring data
                   char*           o_ringName,       // Ring name
                   uint32_t        i_dbgl = 0);      // Debug option

int tor_get_single_ring ( void*
                          i_ringSectionPt,     // Ring address Ptr any of .rings, .overrides and .overlays.
                          uint16_t      i_ddLevel,           // DD level info
                          RingID        i_ringId,            // Unique ring ID
                          PpeType_t     i_PpeType,           // ppe Type
                          RingVariant_t i_RingVariant,       // Base, cache contained, etc
                          uint8_t       i_instanceId,        // Chiplet Instance ID
                          void**        io_ringBlockPtr,     // Addr of ring buffer
                          uint32_t&     io_ringBlockSize,    // size of ring data
                          uint32_t      i_dbgl = 0);      // Debug option

int tor_get_block_of_rings ( void*
                             i_ringSectionPt,  // Ring address Ptr any of .rings, .overrides and .overlays.
                             uint16_t      i_ddLevel,         // DD level
                             PpeType_t     i_PpeType,         // ppe Type
                             RingType_t    i_RingType,        // Common Or Instance
                             RingVariant_t i_RingVariant,     // base,cache,etc
                             uint8_t       i_instanceId,      // Chiplet Instance ID
                             void**        io_ringBlockPtr,   // Addr of ring buffer
                             uint32_t&     io_ringBlockSize, // size of ring data
                             uint32_t      i_dbgl = 0); // Debug option
};

#endif //_P9_TOR_H_
<commit_msg>Rename tor_get_ring API as tor_access_ring<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/utils/imageProcs/p9_tor.H $               */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
#ifndef _P9_TOR_H_
#define _P9_TOR_H_

#include "p9_ring_identification.H"
#include "p9_ringId.H"

namespace P9_TOR
{

#define NUM_RING_IDS              P9_NUM_RINGS

typedef struct
{
    uint32_t sizeOfThis;
    uint16_t sizeOfCmsk;
    uint16_t sizeOfMeta; // Exact size of meta data. Arbitrary size. Not null terminated.
} RingLayout_t;

//
// Temporary define until in TOR header by Giri.
//
//
// Temporary define until in TOR header by Giri.
//
typedef struct
{
    uint32_t TorNumDdLevels;
    uint32_t reserved;
} TorNumDdLevels_t;

typedef struct
{
    uint32_t TorDdLevelAndOffset;
    uint32_t TorDdBlockSize;
} TorDdLevelBlock_t;

typedef struct
{
    uint32_t TorPpeTypeOffset;
    uint32_t TorPpeBlockSize;
} TorPpeBlock_t;

#define IMGBUILD_TGR_RING_FOUND                        0
#define IMGBUILD_TGR_RING_BLOCKS_FOUND                 0
#define IMGBUILD_TGR_RING_NOT_FOUND                    1  // Ring is not found in HW image.
#define IMGBUILD_TGR_INVALID_RING_ID                   2  // Ring is invalid or mismatch.
#define IMGBUILD_TGR_AMBIGUOUS_API_PARMS               3  // Ring search in HW iamge got ambiguous condition.
#define IMGBUILD_TGR_SECTION_NOT_FOUND                 4
#define IMGBUILD_TGR_DD_LVL_INFO_NOT_FOUND             5
#define IMGBUILD_TGR_OP_BUFFER_INVALID                 6
#define IMGBUILD_TGR_OP_BUFFER_SIZE_EXCEEDED           7
#define IMGBUILD_INVALID_INSTANCEID                    8
#define IMGBUILD_TGR_IMAGE_DOES_NOT_SUPPORT_CME       10
#define IMGBUILD_TGR_IMAGE_DOES_NOT_SUPPORT_SGPE      11
#define IMGBUILD_TGR_IMAGE_DOES_NOT_SUPPORT_DD_LEVEL  12
#define IMGBUILD_TGR_IMAGE_DOES_NOT_SUPPORT_PPE_LEVEL 13

extern const char* ringVariantName[];
extern const char* ppeTypeName[];

typedef enum
RingBlockType   // Different options to extract data using tor_access_ring API
{
    SINGLE_RING      = 0x00,
    DD_LEVEL_RINGS   = 0x01,
    PPE_LEVEL_RINGS  = 0x02,
    CPLT_LEVEL_RINGS = 0x03
} RingBlockType_t;

typedef enum RingType      // Different type of Rings
{
    COMMON   = 0x00,
    INSTANCE = 0x01,
    ALLRING  = 0x02
} RingType_t;

typedef enum RingVariant   // Base variables
{
    BASE     = 0x00,
    CC       = 0x01,
    RL       = 0x02,
    OVERRIDE = 0x03,
    OVERLAY  = 0x04,
    NUM_RING_VARIANTS = 0x05,
    NOT_VALID = 0xff
} RingVariant_t;

//
// PPE types
//
typedef enum PpeType
{
    SBE           = 0x00,     // Ppe type partition in Ringsection
    CME           = 0x01,
    SGPE          = 0x02,
    NUM_PPE_TYPES = 0x03
} PpeType_t;

typedef enum RingSectionId
{
    SECTION_RING    = 0x00,    //.ring section ID
    SECTION_OVRD    = 0x01,    //.Override section ID
    SECTION_OVRL    = 0x02     //.Overlay section ID
} RingSectionId_t;

typedef enum SbeTorId
{
    PERV_CPLT = 0,
    N0_CPLT =   1,
    N1_CPLT =   2,
    N2_CPLT =   3,
    N3_CPLT =   4,
    XB_CPLT =   5,
    MC_CPLT =   6,
    OB0_CPLT =  7,
    OB1_CPLT =  8,
    OB2_CPLT =  9,
    OB3_CPLT =  10,
    PCI0_CPLT = 11,
    PCI1_CPLT = 12,
    PCI2_CPLT = 13,
    EQ_CPLT   = 14,
    EC_CPLT   = 15,
    SBE_NOOF_CHIPLETS =   16
} SbeTorId_t;
typedef enum CmeTorId
{
    CME0_CPLT    = 0,
    CME1_CPLT    = 1,
    CME2_CPLT    = 2,
    CME3_CPLT    = 3,
    CME4_CPLT    = 4,
    CME5_CPLT    = 5,
    CME6_CPLT    = 6,
    CME7_CPLT    = 7,
    CME8_CPLT    = 8,
    CME9_CPLT    = 9,
    CME10_CPLT   = 10,
    CME11_CPLT   = 11,
    CME_NOOF_CHIPLETS = 12
} CmeTorId_t;
///
/// ****************************************************************************
/// Function declares.
/// ****************************************************************************
///

int get_ring_from_sbe_image ( void*
                              i_ringSectionPtr, // Image pointer
                              uint64_t        i_magic,          // Image Magic Number
                              RingID          i_ringId,         // Unique ring ID
                              uint16_t        i_ddLevel,        // DD level details
                              RingType_t&     io_RingType,      // 0: Common 1: Instance
                              RingVariant_t   i_RingVariant,    // Base, cache contained, Risk level,
                              // Override and Overlay
                              uint8_t&        io_instanceId,    // required Instance
                              RingBlockType_t RingBlockType,    // 0: single ring,  1: ddLevel block
                              void**          io_ringBlockPtr,  // RS4 Container data or block data
                              uint32_t&       io_ringBlockSize, // size of data copied into ring block pointer
                              char*           o_ringName,       // Name of ring
                              uint32_t        dbgl);            // Debug option

int get_ring_from_sgpe_image ( void*
                               i_ringSectionPtr, // Image pointer
                               RingID          i_ringId,         // Unique ring ID
                               uint16_t        i_ddLevel,        // DD level details
                               RingType_t&      io_RingType,       // 0: Common 1: Instance
                               RingVariant_t   i_RingVariant,    // Base, cache contained, Risk level,
                               // Override and Overlay
                               uint8_t&         io_instanceId,    // required Instance
                               RingBlockType_t RingBlockType,    // 0: single ring,  1: ddLevel block
                               void**          io_ringBlockPtr,   // RS4 Container data or block data
                               uint32_t&       io_ringBlockSize, // size of data copied into ring block pointer
                               char*           o_ringName,       // Name of ring
                               uint32_t        dbgl);            // Debug option

int get_ring_from_cme_image ( void*           i_ringSectionPtr, // Image pointer
                              RingID          i_ringId,         // Unique ring ID
                              uint16_t        i_ddLevel,        // DD level details
                              RingType_t&      io_RingType,       // 0: Common 1: Instance
                              RingVariant_t   i_RingVariant,    // Base, cache contained, Risk level,
                              // Override and Overlay
                              uint8_t&        io_instanceId,    // required Instance
                              RingBlockType_t RingBlockType,    // 0: single ring,  1: ddLevel block
                              void**          io_ringBlockPtr,   // RS4 Container data or block data
                              uint32_t&       io_ringBlockSize, // size of data copied into ring block pointer
                              char*           o_ringName,       // Name of ring
                              uint32_t        dbgl);            // Debug option

int tor_access_ring(  void*
                      i_ringSectionPtr, // Ring address Ptr any of .rings, .overrides and .overlays.
                      uint64_t        i_magic,          // Image Magic Number
                      RingID          i_ringId,         // Unique ring ID
                      uint16_t        i_ddLevel,        // DD level info
                      PpeType_t       i_PpeType,        // PPE type : SBE, CME, etc
                      RingType_t&     io_RingType,      // 0: Common 1: Instance
                      RingVariant_t   i_RingVariant,    // Base, Cache etc
                      uint8_t&        io_instanceId,    // chiplet instance ID
                      RingBlockType_t i_RingBlockType,  // 0: single ring,  1: ring block
                      void**          io_ringBlockPtr,  // Addr of ring buffer
                      uint32_t&       io_ringBlockSize, // size of ring data
                      char*           o_ringName,       // Ring name
                      uint32_t        i_dbgl = 0);      // Debug option

int tor_get_single_ring ( void*
                          i_ringSectionPt,     // Ring address Ptr any of .rings, .overrides and .overlays.
                          uint16_t      i_ddLevel,           // DD level info
                          RingID        i_ringId,            // Unique ring ID
                          PpeType_t     i_PpeType,           // ppe Type
                          RingVariant_t i_RingVariant,       // Base, cache contained, etc
                          uint8_t       i_instanceId,        // Chiplet Instance ID
                          void**        io_ringBlockPtr,     // Addr of ring buffer
                          uint32_t&     io_ringBlockSize,    // size of ring data
                          uint32_t      i_dbgl = 0);         // Debug option

int tor_get_block_of_rings ( void*
                             i_ringSectionPt,  // Ring address Ptr any of .rings, .overrides and .overlays.
                             uint16_t      i_ddLevel,         // DD level
                             PpeType_t     i_PpeType,         // ppe Type
                             RingType_t    i_RingType,        // Common Or Instance
                             RingVariant_t i_RingVariant,     // base,cache,etc
                             uint8_t       i_instanceId,      // Chiplet Instance ID
                             void**        io_ringBlockPtr,   // Addr of ring buffer
                             uint32_t&     io_ringBlockSize,  // size of ring data
                             uint32_t      i_dbgl = 0);       // Debug option
};

#endif //_P9_TOR_H_
<|endoftext|>