diff --git a/libpldmresponder/bios.cpp b/libpldmresponder/bios.cpp
index eab83dc..a899e62 100644
--- a/libpldmresponder/bios.cpp
+++ b/libpldmresponder/bios.cpp
@@ -5,37 +5,36 @@
 #include "xyz/openbmc_project/Common/error.hpp"
 
 #include <array>
+#include <boost/crc.hpp>
 #include <chrono>
 #include <ctime>
 #include <iostream>
+#include <numeric>
+#include <phosphor-logging/elog-errors.hpp>
 #include <phosphor-logging/log.hpp>
 #include <stdexcept>
 #include <string>
 #include <variant>
 #include <vector>
 
+using namespace pldm::responder::bios;
+using namespace bios_parser;
+using namespace bios_parser::bios_enum;
+
 namespace pldm
 {
 
 using namespace phosphor::logging;
-
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
 using EpochTimeUS = uint64_t;
+using BIOSTableRow = std::vector<uint8_t>;
 
 constexpr auto dbusProperties = "org.freedesktop.DBus.Properties";
+constexpr auto padChksumMax = 7;
 
 namespace responder
 {
 
-namespace bios
-{
-
-void registerHandlers()
-{
-    registerHandler(PLDM_BIOS, PLDM_GET_DATE_TIME, std::move(getDateTime));
-}
-
-} // namespace bios
-
 namespace utils
 {
 
@@ -110,5 +109,724 @@
     return response;
 }
 
+/** @brief Generate the next attribute handle
+ *
+ *  @return - uint16_t - next attribute handle
+ */
+AttributeHandle nextAttributeHandle()
+{
+    static AttributeHandle attrHdl = 0;
+    return attrHdl++;
+}
+
+/** @brief Generate the next string handle
+ *  *
+ *  @return - uint16_t - next string handle
+ */
+StringHandle nextStringHandle()
+{
+    static StringHandle strHdl = 0;
+    return strHdl++;
+}
+
+/** @brief Construct the BIOS string table
+ *
+ *  @param[in] BIOSStringTable - the string table
+ *  @param[in] transferHandle - transfer handle to identify part of transfer
+ *  @param[in] transferOpFlag - flag to indicate which part of data being
+ * transferred
+ *  @param[in] instanceID - instance ID to identify the command
+ *  @param[in] biosJsonDir - path where the BIOS json files are present
+ */
+Response getBIOSStringTable(BIOSTable& BIOSStringTable, uint32_t transferHandle,
+                            uint8_t transferOpFlag, uint8_t instanceID,
+                            const char* biosJsonDir)
+{
+    Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
+                      0);
+    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+
+    if (BIOSStringTable.isEmpty())
+    { // no persisted table, constructing fresh table and file
+        auto biosStrings = bios_parser::getStrings(biosJsonDir);
+        std::sort(biosStrings.begin(), biosStrings.end());
+        // remove all duplicate strings received from bios json
+        biosStrings.erase(std::unique(biosStrings.begin(), biosStrings.end()),
+                          biosStrings.end());
+        size_t allStringsLen =
+            std::accumulate(biosStrings.begin(), biosStrings.end(), 0,
+                            [](size_t sum, const std::string& elem) {
+                                return sum + elem.size();
+                            });
+        size_t sizeWithoutPad =
+            allStringsLen +
+            (biosStrings.size() * (sizeof(pldm_bios_string_table_entry) - 1));
+        uint8_t padSize = utils::getNumPadBytes(sizeWithoutPad);
+        uint32_t stringTableSize{};
+        uint32_t checkSum;
+        if (biosStrings.size())
+        {
+            stringTableSize = sizeWithoutPad + padSize + sizeof(checkSum);
+        }
+        Table stringTable(
+            stringTableSize,
+            0); // initializing to 0 so that pad will be automatically added
+        auto tablePtr = reinterpret_cast<uint8_t*>(stringTable.data());
+        for (const auto& elem : biosStrings)
+        {
+            auto stringPtr =
+                reinterpret_cast<struct pldm_bios_string_table_entry*>(
+                    tablePtr);
+
+            stringPtr->string_handle = nextStringHandle();
+            stringPtr->string_length = elem.length();
+            memcpy(stringPtr->name, elem.c_str(), elem.length());
+            tablePtr += sizeof(stringPtr->string_handle) +
+                        sizeof(stringPtr->string_length);
+            tablePtr += elem.length();
+        }
+        tablePtr += padSize;
+
+        if (stringTableSize)
+        {
+            // compute checksum
+            boost::crc_32_type result;
+            result.process_bytes(stringTable.data(), stringTableSize);
+            checkSum = result.checksum();
+            std::copy_n(reinterpret_cast<uint8_t*>(&checkSum), sizeof(checkSum),
+                        stringTable.data() + sizeWithoutPad + padSize);
+            BIOSStringTable.store(stringTable);
+        }
+
+        response.resize(sizeof(pldm_msg_hdr) +
+                            PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES +
+                            stringTableSize,
+                        0);
+        responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+        size_t respPayloadLength = response.size();
+        uint32_t nxtTransferHandle = 0;
+        uint8_t transferFlag = PLDM_START_AND_END;
+        encode_get_bios_table_resp(instanceID, PLDM_SUCCESS, nxtTransferHandle,
+                                   transferFlag, stringTable.data(),
+                                   respPayloadLength, responsePtr);
+    }
+    else
+    { // persisted table present, constructing response
+        size_t respPayloadLength = response.size();
+        uint32_t nxtTransferHandle = 0;
+        uint8_t transferFlag = PLDM_START_AND_END;
+        encode_get_bios_table_resp(instanceID, PLDM_SUCCESS, nxtTransferHandle,
+                                   transferFlag, nullptr, respPayloadLength,
+                                   responsePtr); // filling up the header here
+        BIOSStringTable.load(response);
+    }
+
+    return response;
+}
+
+/** @brief Find the string handle from the BIOS string table given the name
+ *
+ *  @param[in] name - name of the BIOS string
+ *  @param[in] BIOSStringTable - the string table
+ *  @return - uint16_t - handle of the string
+ */
+StringHandle findStringHandle(const std::string& name,
+                              const BIOSTable& BIOSStringTable)
+{
+    StringHandle hdl{};
+    Response response;
+    BIOSStringTable.load(response);
+
+    auto tableData = response.data();
+    size_t tableLen = response.size();
+    auto tableEntry =
+        reinterpret_cast<struct pldm_bios_string_table_entry*>(response.data());
+    while (1)
+    {
+        hdl = tableEntry->string_handle;
+        uint16_t len = tableEntry->string_length;
+        if (memcmp(name.c_str(), tableEntry->name, len) == 0)
+        {
+            break;
+        }
+        tableData += (sizeof(struct pldm_bios_string_table_entry) - 1) + len;
+
+        if (std::distance(tableData, response.data() + tableLen) <=
+            padChksumMax)
+        {
+            log<level::ERR>("Reached end of BIOS string table,did not find the "
+                            "handle for the string",
+                            entry("STRING=%s", name.c_str()));
+            elog<InternalFailure>();
+            break;
+        }
+
+        tableEntry =
+            reinterpret_cast<struct pldm_bios_string_table_entry*>(tableData);
+    }
+    return hdl;
+}
+
+/** @brief Find the string name from the BIOS string table for a string handle
+ *
+ *  @param[in] stringHdl - string handle
+ *  @param[in] BIOSStringTable - the string table
+ *
+ *  @return - std::string - name of the corresponding BIOS string
+ */
+std::string findStringName(StringHandle stringHdl,
+                           const BIOSTable& BIOSStringTable)
+{
+    std::string name;
+    Response response;
+    BIOSStringTable.load(response);
+
+    auto tableData = response.data();
+    size_t tableLen = response.size();
+    auto tableEntry =
+        reinterpret_cast<struct pldm_bios_string_table_entry*>(response.data());
+    while (1)
+    {
+        StringHandle currHdl = tableEntry->string_handle;
+        uint16_t len = tableEntry->string_length;
+        if (currHdl == stringHdl)
+        {
+            name.resize(len);
+            memcpy(name.data(), tableEntry->name, len);
+            break;
+        }
+        tableData += (sizeof(struct pldm_bios_string_table_entry) - 1) + len;
+
+        if (std::distance(tableData, response.data() + tableLen) <=
+            padChksumMax)
+        {
+            log<level::ERR>("Reached end of BIOS string table,did not find "
+                            "string name for handle",
+                            entry("STRING_HANDLE=%d", stringHdl));
+            break;
+        }
+
+        tableEntry =
+            reinterpret_cast<struct pldm_bios_string_table_entry*>(tableData);
+    }
+    return name;
+}
+
+namespace bios_type_enum
+{
+
+/** @brief Find the indices  into the array of the possible values of string
+ *  handles for the current values.This is used in attribute value table
+ *
+ *  @param[in] possiVals - vector of string handles comprising all the possible
+ *                         values for an attribute
+ *  @param[in] currVals - vector of strings comprising all current values
+ *                        for an attribute
+ *  @param[in] BIOSStringTable - the string table
+ *
+ *  @return - std::vector<uint8_t> - indices into the array of the possible
+ *                                   values of string handles
+ */
+std::vector<uint8_t> findStrIndices(PossibleValuesByHandle possiVals,
+                                    CurrentValues currVals,
+                                    const BIOSTable& BIOSStringTable)
+{
+    std::vector<uint8_t> stringIndices;
+
+    for (const auto& currVal : currVals)
+    {
+        StringHandle curHdl;
+        try
+        {
+            curHdl = findStringHandle(currVal, BIOSStringTable);
+        }
+        catch (InternalFailure& e)
+        {
+            log<level::ERR>("Exception fetching handle for the string",
+                            entry("STRING=%s", currVal.c_str()));
+            continue;
+        }
+
+        uint8_t i = 0;
+        for (auto possiHdl : possiVals)
+        {
+            if (possiHdl == curHdl)
+            {
+                stringIndices.push_back(i);
+                break;
+            }
+            i++;
+        }
+    }
+    return stringIndices;
+}
+
+/** @brief Find the indices into the array of the possible values of string
+ *  handles for the default values. This is used in attribute table
+ *
+ *  @param[in] possiVals - vector of strings comprising all the possible values
+ *                         for an attribute
+ *  @param[in] defVals - vector of strings comprising all the default values
+ *                       for an attribute
+ *  @return - std::vector<uint8_t> - indices into the array of the possible
+ *                                   values of string
+ */
+std::vector<uint8_t> findDefaultValHandle(const PossibleValues& possiVals,
+                                          const DefaultValues& defVals)
+{
+    std::vector<uint8_t> defHdls;
+    for (const auto& defs : defVals)
+    {
+        auto index = std::lower_bound(possiVals.begin(), possiVals.end(), defs);
+        if (index != possiVals.end())
+        {
+            defHdls.push_back(index - possiVals.begin());
+        }
+    }
+
+    return defHdls;
+}
+
+/** @brief Construct the attibute table for BIOS type Enumeration and
+ *         Enumeration ReadOnly
+ *  @param[in] BIOSStringTable - the string table
+ *  @param[in] biosJsonDir - path where the BIOS json files are present
+ *
+ *  @return - Table - the attribute eenumeration table
+ */
+Table constructAttrTable(const BIOSTable& BIOSStringTable,
+                         const char* biosJsonDir)
+{
+    setupValueLookup(biosJsonDir);
+    const auto& attributeMap = getValues();
+    Table attributeTable;
+    StringHandle strHandle;
+
+    for (const auto& [key, value] : attributeMap)
+    {
+        try
+        {
+            strHandle = findStringHandle(key, BIOSStringTable);
+        }
+        catch (InternalFailure& e)
+        {
+            log<level::ERR>("Could not find handle for BIOS string",
+                            entry("ATTRIBUTE=%s", key.c_str()));
+            continue;
+        }
+        uint8_t typeOfAttr = (std::get<0>(value))
+                                 ? PLDM_BIOS_ENUMERATION_READ_ONLY
+                                 : PLDM_BIOS_ENUMERATION;
+        PossibleValues possiVals = std::get<1>(value);
+        DefaultValues defVals = std::get<2>(value);
+        // both the possible and default values are stored in sorted manner to
+        // ease in fetching back/comparison
+        std::sort(possiVals.begin(), possiVals.end());
+        std::sort(defVals.begin(), defVals.end());
+
+        std::vector<StringHandle> possiValsByHdl;
+        for (const auto& elem : possiVals)
+        {
+            try
+            {
+                auto hdl = findStringHandle(elem, BIOSStringTable);
+                possiValsByHdl.push_back(std::move(hdl));
+            }
+            catch (InternalFailure& e)
+            {
+                log<level::ERR>("Could not find handle for BIOS string",
+                                entry("STRING=%s", elem.c_str()));
+                continue;
+            }
+        }
+        auto defValsByHdl = findDefaultValHandle(possiVals, defVals);
+
+        BIOSTableRow enumAttrTable(
+            (sizeof(struct pldm_bios_attr_table_entry) - 1) + sizeof(uint8_t) +
+                possiValsByHdl.size() * sizeof(uint16_t) + sizeof(uint8_t) +
+                defValsByHdl.size() * sizeof(uint8_t),
+            0);
+        BIOSTableRow::iterator it = enumAttrTable.begin();
+        auto attrPtr = reinterpret_cast<struct pldm_bios_attr_table_entry*>(
+            enumAttrTable.data());
+        attrPtr->attr_handle = nextAttributeHandle();
+        attrPtr->attr_type = typeOfAttr;
+        attrPtr->string_handle = std::move(strHandle);
+        std::advance(it, (sizeof(struct pldm_bios_attr_table_entry) - 1));
+        uint8_t numPossibleVals = possiValsByHdl.size();
+        std::copy_n(&numPossibleVals, sizeof(numPossibleVals), it);
+        std::advance(it, sizeof(numPossibleVals));
+        std::copy_n(reinterpret_cast<uint8_t*>(possiValsByHdl.data()),
+                    sizeof(uint16_t) * possiValsByHdl.size(), it);
+        std::advance(
+            it, sizeof(uint16_t) *
+                    possiValsByHdl.size()); // possible val handle is uint16_t
+        uint8_t numDefaultVals = defValsByHdl.size();
+        std::copy_n(&numDefaultVals, sizeof(numDefaultVals), it);
+        std::advance(it, sizeof(numDefaultVals));
+        std::copy(defValsByHdl.begin(), defValsByHdl.end(), it);
+        std::advance(it, defValsByHdl.size());
+
+        std::move(enumAttrTable.begin(), enumAttrTable.end(),
+                  std::back_inserter(attributeTable));
+    }
+
+    return attributeTable;
+}
+
+/** @brief Construct the attibute value table for BIOS type Enumeration and
+ *  Enumeration ReadOnly
+ *
+ *  @param[in] BIOSAttributeTable - the attribute table
+ *  @param[in] BIOSStringTable - the string table
+ *
+ *  @return - Table - the attribute value table
+ */
+Table constructAttrValueTable(const BIOSTable& BIOSAttributeTable,
+                              const BIOSTable& BIOSStringTable)
+{
+    Table attributeValueTable;
+    Response response;
+    BIOSAttributeTable.load(response);
+
+    auto tableData = response.data();
+    size_t tableLen = response.size();
+    auto attrPtr =
+        reinterpret_cast<struct pldm_bios_attr_table_entry*>(response.data());
+
+    while (1)
+    {
+        uint16_t attrHdl = attrPtr->attr_handle;
+        uint8_t attrType = attrPtr->attr_type;
+        uint16_t stringHdl = attrPtr->string_handle;
+        tableData += (sizeof(struct pldm_bios_attr_table_entry) - 1);
+        uint8_t numPossiVals = *tableData;
+        tableData++; // pass number of possible values
+        PossibleValuesByHandle possiValsByHdl(numPossiVals, 0);
+        memcpy(possiValsByHdl.data(), tableData,
+               sizeof(uint16_t) * numPossiVals);
+        tableData += sizeof(uint16_t) * numPossiVals;
+        uint8_t numDefVals = *tableData;
+        tableData++;             // pass number of def vals
+        tableData += numDefVals; // pass all the def val indices
+
+        auto attrName = findStringName(stringHdl, BIOSStringTable);
+        if (attrName.empty())
+        {
+            if (std::distance(tableData, response.data() + tableLen) <=
+                padChksumMax)
+            {
+                log<level::ERR>("Did not find string name for handle",
+                                entry("STRING_HANDLE=%d", stringHdl));
+                return attributeValueTable;
+            }
+            attrPtr =
+                reinterpret_cast<struct pldm_bios_attr_table_entry*>(tableData);
+            continue;
+        }
+        CurrentValues currVals;
+        try
+        {
+            currVals = getAttrValue(attrName);
+        }
+        catch (const std::exception& e)
+        {
+            log<level::ERR>(
+                "constructAttrValueTable returned error for attribute",
+                entry("NAME=%s", attrName.c_str()),
+                entry("ERROR=%s", e.what()));
+            if (std::distance(tableData, response.data() + tableLen) <=
+                padChksumMax)
+            {
+                return attributeValueTable;
+            }
+
+            attrPtr =
+                reinterpret_cast<struct pldm_bios_attr_table_entry*>(tableData);
+            continue;
+        }
+        // sorting since the possible values are stored in sorted way
+        std::sort(currVals.begin(), currVals.end());
+        auto currValStrIndices =
+            findStrIndices(possiValsByHdl, currVals, BIOSStringTable);
+        // number of current values equals to the number of string handles
+        // received not the number of strings received from getAttrValue
+        uint8_t numCurrVals = currValStrIndices.size();
+
+        BIOSTableRow enumAttrValTable(
+            (sizeof(struct pldm_bios_attr_val_table_entry) - 1) +
+                sizeof(uint8_t) + numCurrVals * sizeof(uint8_t),
+            0);
+        BIOSTableRow::iterator it = enumAttrValTable.begin();
+        auto attrValPtr =
+            reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
+                enumAttrValTable.data());
+        attrValPtr->attr_handle = attrHdl;
+        attrValPtr->attr_type = attrType;
+        std::advance(it, (sizeof(pldm_bios_attr_val_table_entry) - 1));
+        std::copy_n(&numCurrVals, sizeof(numCurrVals), it);
+        std::advance(it, sizeof(numCurrVals));
+        if (numCurrVals)
+        {
+            std::copy(currValStrIndices.begin(), currValStrIndices.end(), it);
+            std::advance(it, currValStrIndices.size());
+        }
+        std::move(enumAttrValTable.begin(), enumAttrValTable.end(),
+                  std::back_inserter(attributeValueTable));
+
+        if (std::distance(tableData, response.data() + tableLen) <=
+            padChksumMax)
+        {
+            break;
+        }
+
+        attrPtr =
+            reinterpret_cast<struct pldm_bios_attr_table_entry*>(tableData);
+    }
+
+    return attributeValueTable;
+}
+
+} // end namespace bios_type_enum
+
+/** @brief Construct the BIOS attribute table
+ *
+ *  @param[in] BIOSAttributeTable - the attribute table
+ *  @param[in] BIOSStringTable - the string table
+ *  @param[in] transferHandle - transfer handle to identify part of transfer
+ *  @param[in] transferOpFlag - flag to indicate which part of data being
+ * transferred
+ *  @param[in] instanceID - instance ID to identify the command
+ *  @param[in] biosJsonDir - path where the BIOS json files are present
+ */
+Response getBIOSAttributeTable(BIOSTable& BIOSAttributeTable,
+                               const BIOSTable& BIOSStringTable,
+                               uint32_t transferHandle, uint8_t transferOpFlag,
+                               uint8_t instanceID, const char* biosJsonDir)
+{
+    Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
+                      0);
+    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+    uint32_t nxtTransferHandle = 0;
+    uint8_t transferFlag = PLDM_START_AND_END;
+    size_t respPayloadLength{};
+
+    if (BIOSAttributeTable.isEmpty())
+    { // no persisted table, constructing fresh table and response
+        auto attributeTable =
+            bios_type_enum::constructAttrTable(BIOSStringTable, biosJsonDir);
+
+        // calculate pad
+        uint8_t padSize = utils::getNumPadBytes(attributeTable.size());
+        std::vector<uint8_t> pad(padSize, 0);
+        if (padSize)
+        {
+            std::move(pad.begin(), pad.end(),
+                      std::back_inserter(attributeTable));
+        }
+
+        if (!attributeTable.empty())
+        {
+            // compute checksum
+            boost::crc_32_type result;
+            size_t size = attributeTable.size();
+            result.process_bytes(attributeTable.data(), size);
+            uint32_t checkSum = result.checksum();
+            attributeTable.resize(size + sizeof(checkSum));
+            std::copy_n(reinterpret_cast<uint8_t*>(&checkSum), sizeof(checkSum),
+                        attributeTable.data() + size);
+            BIOSAttributeTable.store(attributeTable);
+        }
+        response.resize(sizeof(pldm_msg_hdr) +
+                        PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES +
+                        attributeTable.size());
+        responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+        respPayloadLength = response.size();
+        encode_get_bios_table_resp(instanceID, PLDM_SUCCESS, nxtTransferHandle,
+                                   transferFlag, attributeTable.data(),
+                                   respPayloadLength, responsePtr);
+    }
+    else
+    { // persisted table present, constructing response
+        respPayloadLength = response.size();
+        encode_get_bios_table_resp(instanceID, PLDM_SUCCESS, nxtTransferHandle,
+                                   transferFlag, nullptr, respPayloadLength,
+                                   responsePtr); // filling up the header here
+        BIOSAttributeTable.load(response);
+    }
+
+    return response;
+}
+
+/** @brief Construct the BIOS attribute value table
+ *
+ *  @param[in] BIOSAttributeValueTable - the attribute value table
+ *  @param[in] BIOSAttributeTable - the attribute table
+ *  @param[in] BIOSStringTable - the string table
+ *  @param[in] transferHandle - transfer handle to identify part of transfer
+ *  @param[in] transferOpFlag - flag to indicate which part of data being
+ * transferred
+ *  @param[in] instanceID - instance ID to identify the command
+ *  @param[in] biosJsonDir -  path where the BIOS json files are present
+ */
+Response getBIOSAttributeValueTable(BIOSTable& BIOSAttributeValueTable,
+                                    const BIOSTable& BIOSAttributeTable,
+                                    const BIOSTable& BIOSStringTable,
+                                    uint32_t& transferHandle,
+                                    uint8_t& transferOpFlag, uint8_t instanceID,
+                                    const char* biosJsonDir)
+{
+    Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
+                      0);
+    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+    uint32_t nxtTransferHandle = 0;
+    uint8_t transferFlag = PLDM_START_AND_END;
+    size_t respPayloadLength{};
+
+    if (BIOSAttributeValueTable.isEmpty())
+    { // no persisted table, constructing fresh table and data
+        Table attributeValueTable = bios_type_enum::constructAttrValueTable(
+            BIOSAttributeTable, BIOSStringTable);
+        // calculate pad
+        uint8_t padSize = utils::getNumPadBytes(attributeValueTable.size());
+        std::vector<uint8_t> pad(padSize, 0);
+        if (padSize)
+        {
+            std::move(pad.begin(), pad.end(),
+                      std::back_inserter(attributeValueTable));
+        }
+        if (!attributeValueTable.empty())
+        {
+            // compute checksum
+            boost::crc_32_type result;
+            result.process_bytes(attributeValueTable.data(),
+                                 attributeValueTable.size());
+            uint32_t checkSum = result.checksum();
+            size_t size = attributeValueTable.size();
+            attributeValueTable.resize(size + sizeof(checkSum));
+            std::copy_n(reinterpret_cast<uint8_t*>(&checkSum), sizeof(checkSum),
+                        attributeValueTable.data() + size);
+            BIOSAttributeValueTable.store(attributeValueTable);
+        }
+
+        response.resize(sizeof(pldm_msg_hdr) +
+                        PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES +
+                        attributeValueTable.size());
+        responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+        respPayloadLength = response.size();
+        encode_get_bios_table_resp(instanceID, PLDM_SUCCESS, nxtTransferHandle,
+                                   transferFlag, attributeValueTable.data(),
+                                   respPayloadLength, responsePtr);
+    }
+    else
+    { // persisted table present, constructing response
+        respPayloadLength = response.size();
+        encode_get_bios_table_resp(instanceID, PLDM_SUCCESS, nxtTransferHandle,
+                                   transferFlag, nullptr, respPayloadLength,
+                                   responsePtr); // filling up the header here
+        BIOSAttributeValueTable.load(response);
+    }
+
+    return response;
+}
+
+Response getBIOSTable(const pldm_msg* request, size_t payloadLength)
+{
+    auto response = internal::buildBIOSTables(request, payloadLength,
+                                              BIOS_JSONS_DIR, BIOS_TABLES_DIR);
+
+    return response;
+}
+
+namespace bios
+{
+
+void registerHandlers()
+{
+    registerHandler(PLDM_BIOS, PLDM_GET_DATE_TIME, std::move(getDateTime));
+    registerHandler(PLDM_BIOS, PLDM_GET_BIOS_TABLE, std::move(getBIOSTable));
+}
+
+namespace internal
+{
+
+Response buildBIOSTables(const pldm_msg* request, size_t payloadLength,
+                         const char* biosJsonDir, const char* biosTablePath)
+{
+    Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
+                      0);
+    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+
+    uint32_t transferHandle{};
+    uint8_t transferOpFlag{};
+    uint8_t tableType{};
+
+    auto rc = decode_get_bios_table_req(request, payloadLength, &transferHandle,
+                                        &transferOpFlag, &tableType);
+    if (rc == PLDM_SUCCESS)
+    {
+        BIOSTable BIOSStringTable(
+            ((std::string(biosTablePath) + "/stringTable")).c_str());
+        BIOSTable BIOSAttributeTable(
+            ((std::string(biosTablePath) + "/attributeTable")).c_str());
+        BIOSTable BIOSAttributeValueTable(
+            ((std::string(biosTablePath) + "/attributeValueTable")).c_str());
+        switch (tableType)
+        {
+            case PLDM_BIOS_STRING_TABLE:
+
+                response = getBIOSStringTable(
+                    BIOSStringTable, transferHandle, transferOpFlag,
+                    request->hdr.instance_id, biosJsonDir);
+                break;
+            case PLDM_BIOS_ATTR_TABLE:
+
+                if (BIOSStringTable.isEmpty())
+                {
+                    rc = PLDM_BIOS_TABLE_UNAVAILABLE;
+                }
+                else
+                {
+                    response = getBIOSAttributeTable(
+                        BIOSAttributeTable, BIOSStringTable, transferHandle,
+                        transferOpFlag, request->hdr.instance_id, biosJsonDir);
+                }
+                break;
+            case PLDM_BIOS_ATTR_VAL_TABLE:
+                if (BIOSAttributeTable.isEmpty())
+                {
+                    rc = PLDM_BIOS_TABLE_UNAVAILABLE;
+                }
+                else
+                {
+                    response = getBIOSAttributeValueTable(
+                        BIOSAttributeValueTable, BIOSAttributeTable,
+                        BIOSStringTable, transferHandle, transferOpFlag,
+                        request->hdr.instance_id, biosJsonDir);
+                }
+                break;
+            default:
+                rc = PLDM_INVALID_BIOS_TABLE_TYPE;
+                break;
+        }
+    }
+
+    if (rc != PLDM_SUCCESS)
+    {
+        uint32_t nxtTransferHandle{};
+        uint8_t transferFlag{};
+        size_t respPayloadLength{};
+
+        encode_get_bios_table_resp(request->hdr.instance_id, rc,
+                                   nxtTransferHandle, transferFlag, nullptr,
+                                   respPayloadLength, responsePtr);
+    }
+
+    return response;
+}
+
+} // end namespace internal
+} // namespace bios
+
 } // namespace responder
 } // namespace pldm
