Initial patch for RBC BIOS Config Manager

ResetBIOSSettings is not implemented as part of this patch apart from
that GetAttribute, SetAttribute and setters for BaseBIOSTable,
PendingAttributes is implemeted.

Interface:
xyz.openbmc_project.BIOSConfig.Manager
Properties:
.BaseBIOSTable                         property  a{s(sbsssvva(sv))} 1 "testAttributeName" "xyz.openbmc_pr... emits-change writable
.PendingAttributes                     property  a{s(sv)}           2 "test1" "xyz.openbmc_project.BIOSCo... emits-change writable
.ResetBIOSSettings                     property  s                  "xyz.openbmc_project.BIOSConfig.Manag... emits-change writable
Methods:
.GetAttribute                          method    s                  svv                                      -
.SetAttribute                          method    sv                 -                                        -

Tested:
1. Service is working well.
2. All the dbus methods and properties are shown correctly.
3. Unit test done.
    a). Tree
root@intel-obmc:~# busctl tree xyz.openbmc_project.BIOSConfigManager
`-/xyz
  `-/xyz/openbmc_project
    `-/xyz/openbmc_project/bios_config
      `-/xyz/openbmc_project/bios_config/manager
    b). Instrospect
root@intel-obmc:~# busctl introspect xyz.openbmc_project.BIOSConfigManager /xyz/openbmc_project/bios_config/manager
NAME                                   TYPE      SIGNATURE          RESULT/VALUE                             FLAGS
org.freedesktop.DBus.Introspectable    interface -                  -                                        -
.Introspect                            method    -                  s                                        -
org.freedesktop.DBus.Peer              interface -                  -                                        -
.GetMachineId                          method    -                  s                                        -
.Ping                                  method    -                  -                                        -
org.freedesktop.DBus.Properties        interface -                  -                                        -
.Get                                   method    ss                 v                                        -
.GetAll                                method    s                  a{sv}                                    -
.Set                                   method    ssv                -                                        -
.PropertiesChanged                     signal    sa{sv}as           -                                        -
xyz.openbmc_project.BIOSConfig.Manager interface -                  -                                        -
.GetAttribute                          method    s                  svv                                      -
.SetAttribute                          method    sv                 -                                        -
.BaseBIOSTable                         property  a{s(sbsssvva(sv))} 2 "attr0" "xyz.openbmc_project.BIOSCo... emits-change writable
.PendingAttributes                     property  a{s(sv)}           1 "test1" "xyz.openbmc_project.BIOSCo... emits-change writable
.ResetBIOSSettings                     property  s                  "xyz.openbmc_project.BIOSConfig.Manag... emits-change writable
    c). Method: GetAttribute/SetAttribute
root@intel-obmc:~# busctl call  xyz.openbmc_project.BIOSConfigManager /xyz/openbmc_project/bios_config/manager xyz.openbmc_project.BIOSConfig.Manager SetAttribute sv test1 s "value"
root@intel-obmc:~# busctl call  xyz.openbmc_project.BIOSConfigManager /xyz/openbmc_project/bios_config/manager xyz.openbmc_project.BIOSConfig.Manager GetAttribute s test1
svv "xyz.openbmc_project.BIOSConfig.Manager.AttributeType.String" x 0 s "value"
    d). Service
root@intel-obmc:~# systemctl status xyz.openbmc_project.biosconfig_manager
* xyz.openbmc_project.biosconfig_manager.service - BIOS Config Manager - For Remote BIOS configuration update
     Loaded: loaded (8;;file://intel-obmc/lib/systemd/system/xyz.openbmc_project.biosconfig_manager.service/lib/systemd/system/xyz.openbmc_project.biosconfig_manager.service8;;; enabled; vendor preset: enabled)
    Drop-In: /etc/systemd/system/xyz.openbmc_project.biosconfig_manager.service.d
             `-8;;file://intel-obmc/etc/systemd/system/xyz.openbmc_project.biosconfig_manager.service.d/watchdog.confwatchdog.conf8;;
     Active: active (running) since Thu 1970-01-01 00:00:56 UTC; 25min ago
   Main PID: 394 (biosconfig-mana)
     CGroup: /system.slice/xyz.openbmc_project.biosconfig_manager.service
             `-394 /usr/bin/biosconfig-manager

Jan 01 00:00:56 intel-obmc systemd[1]: Started BIOS Config Manager - For Remote BIOS configuration update.

Change-Id: I7a7312ffbdf000aab254c77ed5e4f9a8d4ec4d45
Signed-off-by: Kuiying Wang <kuiying.wang@intel.com>
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..52ac0a1
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,115 @@
+---
+Language:        Cpp
+# BasedOnStyle:  LLVM
+AccessModifierOffset: -2
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlines: Right
+AlignOperands:   true
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: None
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: Yes
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:
+  AfterCaseLabel:  true
+  AfterClass:      true
+  AfterControlStatement: true
+  AfterEnum:       true
+  AfterFunction:   true
+  AfterNamespace:  true
+  AfterObjCDeclaration: true
+  AfterStruct:     true
+  AfterUnion:      true
+  AfterExternBlock: true
+  BeforeCatch:     true
+  BeforeElse:      true
+  IndentBraces:    false
+  SplitEmptyFunction:   false
+  SplitEmptyRecord:     false
+  SplitEmptyNamespace:  false
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Custom
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializers: AfterColon
+BreakInheritanceList: AfterColon
+BreakStringLiterals: true
+ColumnLimit:     80
+CommentPragmas:  '^ IWYU pragma:'
+CompactNamespaces: false
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: false
+PointerAlignment: Left
+DisableFormat:   false
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: true
+ForEachMacros:   [ foreach, Q_FOREACH, BOOST_FOREACH ]
+IncludeBlocks: Regroup
+IncludeCategories:
+  - Regex:           '^[<"](gtest|gmock)'
+    Priority:        7
+  - Regex:           '^"config.h"'
+    Priority:        -1
+  - Regex:           '^".*\.h"'
+    Priority:        1
+  - Regex:           '^".*\.hpp"'
+    Priority:        2
+  - Regex:           '^<.*\.h>'
+    Priority:        3
+  - Regex:           '^<.*\.hpp>'
+    Priority:        4
+  - Regex:           '^<.*'
+    Priority:        5
+  - Regex:           '.*'
+    Priority:        6
+IndentCaseLabels: true
+IndentWidth:     4
+IndentWrappedFunctionNames: true
+KeepEmptyLinesAtTheStartOfBlocks: true
+MacroBlockBegin: ''
+MacroBlockEnd:   ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 60
+ReflowComments:  true
+SortIncludes:    true
+SortUsingDeclarations: true
+SpaceAfterCStyleCast: false
+SpaceAfterTemplateKeyword: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeCpp11BracedList: false
+SpaceBeforeCtorInitializerColon: true
+SpaceBeforeInheritanceColon: true
+SpaceBeforeParens: ControlStatements
+SpaceBeforeRangeBasedForLoopColon: true
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles:  false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard:        Latest
+TabWidth:        4
+UseTab:          Never
+...
+
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b95a3ac
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+# meson
+
+/build
+/builddir
diff --git a/LICENSE b/LICENSE
new file mode 100755
index 0000000..20af752
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2020 Intel Corporation
+
+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.
diff --git a/MAINTAINERS b/MAINTAINERS
new file mode 100755
index 0000000..48467bb
--- /dev/null
+++ b/MAINTAINERS
@@ -0,0 +1,46 @@
+How to use this list:
+    Find the most specific section entry (described below) that matches where
+    your change lives and add the reviewers (R) and maintainers (M) as
+    reviewers. You can use the same method to track down who knows a particular
+    code base best.
+
+    Your change/query may span multiple entries; that is okay.
+
+    If you do not find an entry that describes your request at all, someone
+    forgot to update this list; please at least file an issue or send an email
+    to a maintainer, but preferably you should just update this document.
+
+Description of section entries:
+
+    Section entries are structured according to the following scheme:
+
+    X:  NAME <EMAIL_USERNAME@DOMAIN> <IRC_USERNAME!>
+    X:  ...
+    .
+    .
+    .
+
+    Where REPO_NAME is the name of the repository within the OpenBMC GitHub
+    organization; FILE_PATH is a file path within the repository, possibly with
+    wildcards; X is a tag of one of the following types:
+
+    M:  Denotes maintainer; has fields NAME <EMAIL_USERNAME@DOMAIN> <IRC_USERNAME!>;
+        if omitted from an entry, assume one of the maintainers from the
+        MAINTAINERS entry.
+    R:  Denotes reviewer; has fields NAME <EMAIL_USERNAME@DOMAIN> <IRC_USERNAME!>;
+        these people are to be added as reviewers for a change matching the repo
+        path.
+    F:  Denotes forked from an external repository; has fields URL.
+
+    Line comments are to be denoted "# SOME COMMENT" (typical shell style
+    comment); it is important to follow the correct syntax and semantics as we
+    may want to use automated tools with this file in the future.
+
+    A change cannot be added to an OpenBMC repository without a MAINTAINER's
+    approval; thus, a MAINTAINER should always be listed as a reviewer.
+
+START OF MAINTAINERS LIST
+-------------------------
+
+M:  Suryakanth Sekar <suryakanth.sekar@linux.intel.com> <ssekar!>
+M:  Kuiying Wang <kuiying.wang@intel.com> <kuiyingw!>
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100755
index 0000000..ce38e82
--- /dev/null
+++ b/README.md
@@ -0,0 +1,79 @@
+Remote BIOS Configuration via BMC
+Overview
+Provides ability for the user to view and modify the
+BIOS setup configuration parameters remotely via BMC at any Host state.
+Modifications to the parameters take place upon the next system reboot or
+immediate based on the host firmware.
+Please refer https://github.com/openbmc/docs/blob/master/designs/remoteBIOSConfiguration.md
+
+Remote BIOS Configuration (RBC) service exposes D-Bus methods for
+BIOS settings management operations.
+
+RBC Manager Interface
+xyz.openbmc_project.BIOSConfig.Manager provides following methods, properties.
+
+Object Path : /xyz/openbmc_project/BIOSConfig/Manager
+
+xyz.openbmc_project.BIOSConfig.Manager
+
+methods:
+SetAttribute -To set the particular BIOS attribute  with new value.
+GetAttribute -To get the bios attribute current values and pending values if again.
+
+Properites:
+ResetBIOSSettings - Contain reset BIOS setting type:
+					Interface have to set NoAction this property,
+					when Reset BIOS settings are informed to the BIOS.
+BaseBIOSTable - Save the whole BIOS table.
+              map{attributeName,struct{attributeType,readonlyStatus,displayname,
+              description,menuPath,current,default,
+              array{struct{optionstring,optionvalue}}}}
+              Example 1:
+              {"DdrFreqLimit",
+              {xyz.openbmc_project.BIOSConfig.Manager.AttributeType.String,
+               false,
+               "Memory Operating Speed Selection",
+               "Force specific Memory Operating Speed or use Auto setting.",
+               "Advanced/Memory Configuration/Memory Operating Speed Selection",
+               "0x00",
+               "0x0B",
+               { {"OneOf", "auto"},
+                 {"OneOf", "2133"},
+                 {"OneOf", "2400"},
+                 {"OneOf", "2664"},
+                 {"OneOf", "2933"}
+               }
+              }
+              }
+               Example 2:
+              {"BIOSSerialDebugLevel",
+              {xyz.openbmc_project.BIOSConfig.Manager.AttributeType.Integer,
+               false,
+               "BIOS Serial Debug level",
+               "BIOS Serial Debug level during system boot.",
+               "Advanced/Debug Feature Selection",
+               0x00,
+               0x01,
+               { {"MinBound", 0},
+                 {"MaxBound", 4},
+                 {"ScalarIncrement",1}
+               }
+              }
+              }
+
+Signals:
+AttributeChanged - Signal sent out when attribute is changed
+
+PasswordInterface:
+
+xyz.openbmc_project.BIOSConfig.Password provides following Methods and Properities.
+
+xyz.openbmc_project.BIOSConfig.Password Interface
+
+Methods:
+ChangePassword - Change the BIOS setup password.
+
+Properities:
+PasswordInitialized - To indicate BIOS password related details are recevied or not.
+
+
diff --git a/include/manager.hpp b/include/manager.hpp
new file mode 100644
index 0000000..702e30f
--- /dev/null
+++ b/include/manager.hpp
@@ -0,0 +1,136 @@
+/*
+// Copyright (c) 2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+#pragma once
+
+#include <sdbusplus/asio/object_server.hpp>
+#include <sdbusplus/server.hpp>
+#include <xyz/openbmc_project/BIOSConfig/Manager/server.hpp>
+
+#include <string>
+
+namespace bios_config
+{
+
+static constexpr auto service = "xyz.openbmc_project.BIOSConfigManager";
+static constexpr auto objectPath = "/xyz/openbmc_project/bios_config/manager";
+
+using Base = sdbusplus::xyz::openbmc_project::BIOSConfig::server::Manager;
+
+/** @class Manager
+ *
+ *  @brief Implements the BIOS Manager
+ */
+class Manager : public Base
+{
+  public:
+    using BaseTable = std::map<
+        std::string,
+        std::tuple<AttributeType, bool, std::string, std::string, std::string,
+                   std::variant<int64_t, std::string>,
+                   std::variant<int64_t, std::string>,
+                   std::vector<std::tuple<
+                       BoundType, std::variant<int64_t, std::string>>>>>;
+
+    using PendingAttributes =
+        std::map<std::string,
+                 std::tuple<AttributeType, std::variant<int64_t, std::string>>>;
+
+    using PendingAttribute =
+        std::tuple<AttributeType, std::variant<int64_t, std::string>>;
+
+    using AttributeName = std::string;
+    using AttributeValue = std::variant<int64_t, std::string>;
+    using CurrentValue = std::variant<int64_t, std::string>;
+    using PendingValue = std::variant<int64_t, std::string>;
+    using AttributeDetails =
+        std::tuple<AttributeType, CurrentValue, PendingValue>;
+
+    Manager() = delete;
+    ~Manager() = default;
+    Manager(const Manager&) = delete;
+    Manager& operator=(const Manager&) = delete;
+    Manager(Manager&&) = delete;
+    Manager& operator=(Manager&&) = delete;
+
+    /** @brief Constructs Manager object.
+     *
+     *  @param[in] objectServer  - object server
+     *  @param[in] systemBus - bus connection
+     */
+    Manager(sdbusplus::asio::object_server& objectServer,
+            std::shared_ptr<sdbusplus::asio::connection>& systemBus);
+
+    /** @brief Set the BIOS attribute with a new value, the new value is added
+     *         to the PendingAttribute.
+     *
+     *  @param[in] attribute - attribute name
+     *  @param[in] value - new value for the attribute
+     *
+     *  @return On error, throw exception
+     */
+    void setAttribute(AttributeName attribute, AttributeValue value) override;
+
+    /** @brief Get the details of the BIOS attribute
+     *
+     *  @param[in] attribute - attribute name
+     *
+     *  @return On success, return the attribute details: attribute type,
+     *          current value, pending value. On error, throw exception
+     */
+    AttributeDetails getAttribute(AttributeName attribute) override;
+
+    /** @brief Set the BaseBIOSTable property and clears the PendingAttributes
+     *         property
+     *
+     *  @param[in] value - new BaseBIOSTable
+     *
+     *  @return The new BaseBIOSTable that is applied.
+     */
+    BaseTable baseBIOSTable(BaseTable value) override;
+
+    /** @brief Set the PendingAttributes property, additionally checks if the
+     *         attributes are in the BaseBIOSTable, whether the attributes are
+     *         read only and validate the attribute value based on the
+     *         attribute type. PendingAttributes is cleared if value is empty.
+     *
+     *  @param[in] value - new PendingAttributes to append to the
+     *                     PendingAttributes property
+     *
+     *  @return On success, return the new PendingAttributes property that is
+     *          set.Throw exception if the validation fails.
+     */
+    PendingAttributes pendingAttributes(PendingAttributes value) override;
+
+  private:
+    /** @enum Index into the fields in the BaseBIOSTable
+     */
+    enum class Index : uint8_t
+    {
+        attributeType = 0,
+        readOnly,
+        displayName,
+        description,
+        menuPath,
+        currentValue,
+        defaultValue,
+        options,
+    };
+
+    sdbusplus::asio::object_server& objServer;
+    std::shared_ptr<sdbusplus::asio::connection>& systemBus;
+};
+
+} // namespace bios_config
diff --git a/meson.build b/meson.build
new file mode 100755
index 0000000..e99c122
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,53 @@
+project(
+    'biosconfig-manager',
+    'cpp',
+    default_options: [
+        'warning_level=3',
+        'werror=true',
+        'cpp_std=c++17'
+    ],
+    license: 'Apache-2.0',
+    version: '1.0',
+)
+
+# Wno-psabi reduces the number of "Note:" messages when cross-compiling some STL
+# stuff for ARM. See https://stackoverflow.com/questions/48149323/strange-gcc-warning-when-compiling-qt-project
+# Basically, gcc 6 and gcc 7 are not ABI compatible, but since the whole OpenBMC
+# project uses the same compiler, we can safely ignmore these info notes.
+add_project_arguments('-Wno-psabi', language: 'cpp')
+
+boost_args = ['-DBOOST_ALL_NO_LIB',
+              '-DBOOST_ASIO_DISABLE_THREADS',
+              '-DBOOST_ERROR_CODE_HEADER_ONLY',
+              '-DBOOST_NO_RTTI',
+              '-DBOOST_NO_TYPEID',
+              '-DBOOST_SYSTEM_NO_DEPRECATED']
+
+deps = [dependency('boost'),
+        dependency('phosphor-dbus-interfaces'),
+        dependency('phosphor-logging'),
+        dependency('sdbusplus'),
+        dependency('systemd'),
+]
+
+executable('biosconfig-manager',
+           'src/manager.cpp',
+        implicit_include_directories: false,
+        include_directories: ['include'],
+        dependencies: deps,
+        cpp_args : boost_args,
+        install: true,
+        install_dir: get_option('bindir'))
+
+systemd = dependency('systemd')
+systemd_system_unit_dir = systemd.get_pkgconfig_variable(
+    'systemdsystemunitdir',
+    define_variable: ['prefix', get_option('prefix')])
+
+configure_file(
+    copy: true,
+    input: 'service_files/xyz.openbmc_project.biosconfig_manager.service',
+    install: true,
+    install_dir: systemd_system_unit_dir,
+    output: 'xyz.openbmc_project.biosconfig_manager.service'
+)
diff --git a/service_files/xyz.openbmc_project.biosconfig_manager.service b/service_files/xyz.openbmc_project.biosconfig_manager.service
new file mode 100755
index 0000000..982f86b
--- /dev/null
+++ b/service_files/xyz.openbmc_project.biosconfig_manager.service
@@ -0,0 +1,12 @@
+[Unit]
+Description= BIOS Config Manager - For Remote BIOS configuration update
+
+[Service]
+Restart=always
+ExecStart=/usr/bin/biosconfig-manager
+SyslogIdentifier=biosconfig-manager
+Type=dbus
+BusName=xyz.openbmc_project.BIOSConfigManager
+
+[Install]
+WantedBy=multi-user.target
diff --git a/src/manager.cpp b/src/manager.cpp
new file mode 100644
index 0000000..c4c660d
--- /dev/null
+++ b/src/manager.cpp
@@ -0,0 +1,281 @@
+/*
+// Copyright (c) 2020 Intel Corporation
+//
+// 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.
+*/
+#include "manager.hpp"
+
+#include "xyz/openbmc_project/BIOSConfig/Common/error.hpp"
+#include "xyz/openbmc_project/Common/error.hpp"
+
+#include <boost/asio.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+
+namespace bios_config
+{
+
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+using namespace sdbusplus::xyz::openbmc_project::BIOSConfig::Common::Error;
+
+void Manager::setAttribute(AttributeName attribute, AttributeValue value)
+{
+    auto pendingAttrs = Base::pendingAttributes();
+    auto iter = pendingAttrs.find(attribute);
+
+    if (iter != pendingAttrs.end())
+    {
+        std::get<1>(iter->second) = value;
+    }
+    else
+    {
+        Manager::PendingAttribute attributeValue;
+
+        if (std::get_if<int64_t>(&value))
+        {
+            std::get<0>(attributeValue) = AttributeType::Integer;
+        }
+        else
+        {
+            std::get<0>(attributeValue) = AttributeType::String;
+        }
+
+        std::get<1>(attributeValue) = value;
+        pendingAttrs.emplace(attribute, attributeValue);
+    }
+
+    pendingAttributes(pendingAttrs);
+}
+
+Manager::AttributeDetails Manager::getAttribute(AttributeName attribute)
+{
+    Manager::AttributeDetails value;
+
+    auto table = Base::baseBIOSTable();
+    auto iter = table.find(attribute);
+
+    if (iter != table.end())
+    {
+        std::get<0>(value) =
+            std::get<static_cast<uint8_t>(Index::attributeType)>(iter->second);
+        std::get<1>(value) =
+            std::get<static_cast<uint8_t>(Index::currentValue)>(iter->second);
+
+        auto pending = Base::pendingAttributes();
+        auto pendingIter = pending.find(attribute);
+        if (pendingIter != pending.end())
+        {
+            std::get<2>(value) = std::get<1>(pendingIter->second);
+        }
+        else if (std::get_if<std::string>(&std::get<1>(value)))
+        {
+            std::get<2>(value) = std::string();
+        }
+    }
+    else
+    {
+        throw AttributeNotFound();
+    }
+
+    return value;
+}
+
+Manager::BaseTable Manager::baseBIOSTable(BaseTable value)
+{
+    pendingAttributes({});
+    return Base::baseBIOSTable(value, false);
+}
+
+Manager::PendingAttributes Manager::pendingAttributes(PendingAttributes value)
+{
+    // Clear the pending attributes
+    if (value.empty())
+    {
+        return Base::pendingAttributes({}, false);
+    }
+
+    // Validate all the BIOS attributes before setting PendingAttributes
+    BaseTable biosTable = Base::baseBIOSTable();
+    for (const auto& pair : value)
+    {
+        auto iter = biosTable.find(pair.first);
+        // BIOS attribute not found in the BaseBIOSTable
+        if (iter == biosTable.end())
+        {
+            throw AttributeNotFound();
+        }
+
+        // BIOS attribute is read only
+        if (std::get<static_cast<uint8_t>(Index::readOnly)>(iter->second))
+        {
+            throw AttributeReadOnly();
+        }
+
+        auto attributeType =
+            std::get<static_cast<uint8_t>(Index::attributeType)>(iter->second);
+        if (attributeType != std::get<0>(pair.second))
+        {
+            throw InvalidArgument();
+        }
+
+        // Validate enumeration BIOS attributes
+        if (attributeType == AttributeType::Enumeration)
+        {
+            // For enumeration the expected variant types is std::string
+            if (std::get<1>(pair.second).index() == 0)
+            {
+                throw InvalidArgument();
+            }
+
+            const auto& attrValue =
+                std::get<std::string>(std::get<1>(pair.second));
+            const auto& options =
+                std::get<static_cast<uint8_t>(Index::options)>(iter->second);
+
+            bool found = false;
+            for (const auto& enumOptions : options)
+            {
+                if ((BoundType::OneOf == std::get<0>(enumOptions)) &&
+                    (attrValue ==
+                     std::get<std::string>(std::get<1>(enumOptions))))
+                {
+                    found = true;
+                    break;
+                }
+            }
+
+            if (!found)
+            {
+                throw InvalidArgument();
+            }
+        }
+
+        if (attributeType == AttributeType::String)
+        {
+            // For enumeration the expected variant types is std::string
+            if (std::get<1>(pair.second).index() == 0)
+            {
+                throw InvalidArgument();
+            }
+
+            const auto& attrValue =
+                std::get<std::string>(std::get<1>(pair.second));
+            const auto& options =
+                std::get<static_cast<uint8_t>(Index::options)>(iter->second);
+            int64_t minStringLength = 0;
+            int64_t maxStringLength = 0;
+
+            for (const auto& stringOptions : options)
+            {
+                if (BoundType::MinStringLength == std::get<0>(stringOptions))
+                {
+                    minStringLength =
+                        std::get<int64_t>(std::get<1>(stringOptions));
+                }
+                else if (BoundType::MaxStringLength ==
+                         std::get<0>(stringOptions))
+                {
+                    maxStringLength =
+                        std::get<int64_t>(std::get<1>(stringOptions));
+                }
+            }
+
+            if ((attrValue.length() < static_cast<size_t>(minStringLength)) ||
+                (attrValue.length() > static_cast<size_t>(maxStringLength)))
+            {
+                throw InvalidArgument();
+            }
+        }
+
+        if (attributeType == AttributeType::Integer)
+        {
+            // For enumeration the expected variant types is std::string
+            if (std::get<1>(pair.second).index() == 1)
+            {
+                throw InvalidArgument();
+            }
+
+            const auto& attrValue = std::get<int64_t>(std::get<1>(pair.second));
+            const auto& options =
+                std::get<static_cast<uint8_t>(Index::options)>(iter->second);
+            int64_t lowerBound = 0;
+            int64_t upperBound = 0;
+            int64_t scalarIncrement = 0;
+
+            for (const auto& integerOptions : options)
+            {
+                if (BoundType::LowerBound == std::get<0>(integerOptions))
+                {
+                    lowerBound = std::get<int64_t>(std::get<1>(integerOptions));
+                }
+                else if (BoundType::UpperBound == std::get<0>(integerOptions))
+                {
+                    upperBound = std::get<int64_t>(std::get<1>(integerOptions));
+                }
+                else if (BoundType::ScalarIncrement ==
+                         std::get<0>(integerOptions))
+                {
+                    scalarIncrement =
+                        std::get<int64_t>(std::get<1>(integerOptions));
+                }
+            }
+
+            if ((attrValue < lowerBound) || (attrValue > upperBound))
+            {
+                throw InvalidArgument();
+            }
+
+            if (((std::abs(attrValue - lowerBound)) % scalarIncrement) != 0)
+            {
+                throw InvalidArgument();
+            }
+        }
+    }
+
+    PendingAttributes pendingAttribute = Base::pendingAttributes();
+
+    for (const auto& pair : value)
+    {
+        auto iter = pendingAttribute.find(pair.first);
+        if (iter != pendingAttribute.end())
+        {
+            iter = pendingAttribute.erase(iter);
+        }
+
+        pendingAttribute.emplace(std::make_pair(pair.first, pair.second));
+    }
+
+    return Base::pendingAttributes(pendingAttribute, false);
+}
+
+Manager::Manager(sdbusplus::asio::object_server& objectServer,
+                 std::shared_ptr<sdbusplus::asio::connection>& systemBus) :
+    sdbusplus::xyz::openbmc_project::BIOSConfig::server::Manager(*systemBus,
+                                                                 objectPath),
+    objServer(objectServer), systemBus(systemBus)
+{}
+
+} // namespace bios_config
+
+int main()
+{
+    boost::asio::io_service io;
+    auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
+
+    systemBus->request_name(bios_config::service);
+    sdbusplus::asio::object_server objectServer(systemBus);
+    bios_config::Manager manager(objectServer, systemBus);
+
+    io.run();
+    return 0;
+}