/*
 * Copyright (c) 2008 The Hewlett-Packard Development Company
 * All rights reserved.
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2008 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 */

#include "arch/x86/bios/smbios.hh"

#include "arch/x86/isa_traits.hh"
#include "base/types.hh"
#include "mem/port_proxy.hh"
#include "params/X86SMBiosBiosInformation.hh"
#include "params/X86SMBiosSMBiosStructure.hh"
#include "params/X86SMBiosSMBiosTable.hh"
#include "sim/byteswap.hh"

using namespace std;

const char X86ISA::SMBios::SMBiosTable::SMBiosHeader::anchorString[] = "_SM_";
const uint8_t X86ISA::SMBios::SMBiosTable::
        SMBiosHeader::formattedArea[] = {0,0,0,0,0};
const uint8_t X86ISA::SMBios::SMBiosTable::
        SMBiosHeader::entryPointLength = 0x1F;
const uint8_t X86ISA::SMBios::SMBiosTable::
        SMBiosHeader::entryPointRevision = 0;
const char X86ISA::SMBios::SMBiosTable::
        SMBiosHeader::IntermediateHeader::anchorString[] = "_DMI_";

template <class T>
uint64_t
composeBitVector(T vec)
{
    uint64_t val = 0;
    typename T::iterator vecIt;
    for (vecIt = vec.begin(); vecIt != vec.end(); vecIt++) {
        val |= (1 << (*vecIt));
    }
    return val;
}

uint16_t
X86ISA::SMBios::SMBiosStructure::writeOut(PortProxy& proxy, Addr addr)
{
    proxy.writeBlob(addr, &type, 1);

    uint8_t length = getLength();
    proxy.writeBlob(addr + 1, &length, 1);

    uint16_t handleGuest = htole(handle);
    proxy.writeBlob(addr + 2, &handleGuest, 2);

    return length + getStringLength();
}

X86ISA::SMBios::SMBiosStructure::SMBiosStructure(Params * p, uint8_t _type) :
    SimObject(p), type(_type), handle(0), stringFields(false)
{}

void
X86ISA::SMBios::SMBiosStructure::writeOutStrings(
        PortProxy& proxy, Addr addr)
{
    std::vector<std::string>::iterator it;
    Addr offset = 0;

    const uint8_t nullTerminator = 0;

    // If there are string fields but none of them are used, that's a
    // special case which is handled by this if.
    if (strings.size() == 0 && stringFields) {
        proxy.writeBlob(addr + offset, &nullTerminator, 1);
        offset++;
    } else {
        for (it = strings.begin(); it != strings.end(); it++) {
            proxy.writeBlob(addr + offset, it->c_str(), it->length() + 1);
            offset += it->length() + 1;
        }
    }
    proxy.writeBlob(addr + offset, &nullTerminator, 1);
}

int
X86ISA::SMBios::SMBiosStructure::getStringLength()
{
    int size = 0;
    std::vector<std::string>::iterator it;

    for (it = strings.begin(); it != strings.end(); it++) {
        size += it->length() + 1;
    }

    return size + 1;
}

int
X86ISA::SMBios::SMBiosStructure::addString(string & newString)
{
    stringFields = true;
    // If a string is empty, treat it as not existing. The index for empty
    // strings is 0.
    if (newString.length() == 0)
        return 0;
    strings.push_back(newString);
    return strings.size();
}

string
X86ISA::SMBios::SMBiosStructure::readString(int n)
{
    assert(n > 0 && n <= strings.size());
    return strings[n - 1];
}

void
X86ISA::SMBios::SMBiosStructure::setString(int n, std::string & newString)
{
    assert(n > 0 && n <= strings.size());
    strings[n - 1] = newString;
}

X86ISA::SMBios::BiosInformation::BiosInformation(Params * p) :
        SMBiosStructure(p, Type),
        startingAddrSegment(p->starting_addr_segment),
        romSize(p->rom_size),
        majorVer(p->major), minorVer(p->minor),
        embContFirmwareMajor(p->emb_cont_firmware_major),
        embContFirmwareMinor(p->emb_cont_firmware_minor)
    {
        vendor = addString(p->vendor);
        version = addString(p->version);
        releaseDate = addString(p->release_date);

        characteristics = composeBitVector(p->characteristics);
        characteristicExtBytes =
            composeBitVector(p->characteristic_ext_bytes);
    }

uint16_t
X86ISA::SMBios::BiosInformation::writeOut(PortProxy& proxy, Addr addr)
{
    uint8_t size = SMBiosStructure::writeOut(proxy, addr);

    proxy.writeBlob(addr + 0x4, &vendor, 1);
    proxy.writeBlob(addr + 0x5, &version, 1);

    uint16_t startingAddrSegmentGuest = htole(startingAddrSegment);
    proxy.writeBlob(addr + 0x6, &startingAddrSegmentGuest, 2);

    proxy.writeBlob(addr + 0x8, &releaseDate, 1);
    proxy.writeBlob(addr + 0x9, &romSize, 1);

    uint64_t characteristicsGuest = htole(characteristics);
    proxy.writeBlob(addr + 0xA, &characteristicsGuest, 8);

    uint16_t characteristicExtBytesGuest =
        htole(characteristicExtBytes);
    proxy.writeBlob(addr + 0x12, &characteristicExtBytesGuest, 2);

    proxy.writeBlob(addr + 0x14, &majorVer, 1);
    proxy.writeBlob(addr + 0x15, &minorVer, 1);
    proxy.writeBlob(addr + 0x16, &embContFirmwareMajor, 1);
    proxy.writeBlob(addr + 0x17, &embContFirmwareMinor, 1);

    writeOutStrings(proxy, addr + getLength());

    return size;
}

X86ISA::SMBios::SMBiosTable::SMBiosTable(Params * p) :
    SimObject(p), structures(p->structures)
{
    smbiosHeader.majorVersion = p->major_version;
    smbiosHeader.minorVersion = p->minor_version;
    assert(p->major_version <= 9);
    assert(p->minor_version <= 9);
    smbiosHeader.intermediateHeader.smbiosBCDRevision =
        (p->major_version << 4) | p->minor_version;
}

void
X86ISA::SMBios::SMBiosTable::writeOut(PortProxy& proxy, Addr addr,
        Addr &headerSize, Addr &structSize)
{
    headerSize = 0x1F;

    /*
     * The main header
     */
    uint8_t mainChecksum = 0;

    proxy.writeBlob(addr, (uint8_t *)smbiosHeader.anchorString, 4);
    for (int i = 0; i < 4; i++)
        mainChecksum += smbiosHeader.anchorString[i];

    // The checksum goes here, but we're figuring it out as we go.

    proxy.writeBlob(addr + 0x5, &smbiosHeader.entryPointLength, 1);
    mainChecksum += smbiosHeader.entryPointLength;
    proxy.writeBlob(addr + 0x6, &smbiosHeader.majorVersion, 1);
    mainChecksum += smbiosHeader.majorVersion;
    proxy.writeBlob(addr + 0x7, &smbiosHeader.minorVersion, 1);
    mainChecksum += smbiosHeader.minorVersion;
    // Maximum structure size goes here, but we'll figure it out later.
    proxy.writeBlob(addr + 0xA, &smbiosHeader.entryPointRevision, 1);
    mainChecksum += smbiosHeader.entryPointRevision;
    proxy.writeBlob(addr + 0xB, &smbiosHeader.formattedArea, 5);
    for (int i = 0; i < 5; i++)
        mainChecksum += smbiosHeader.formattedArea[i];

    /*
     * The intermediate header
     */
    uint8_t intChecksum = 0;

    proxy.writeBlob(addr + 0x10,
            smbiosHeader.intermediateHeader.anchorString, 5);
    for (int i = 0; i < 5; i++)
        intChecksum += smbiosHeader.intermediateHeader.anchorString[i];

    // The checksum goes here, but we're figuring it out as we go.
    // Then the length of the structure table which we'll find later

    uint32_t tableAddrGuest =
        htole(smbiosHeader.intermediateHeader.tableAddr);
    proxy.writeBlob(addr + 0x18, &tableAddrGuest, 4);
    for (int i = 0; i < 4; i++) {
        intChecksum += tableAddrGuest;
        tableAddrGuest >>= 8;
    }

    uint16_t numStructs = letoh(structures.size());
    proxy.writeBlob(addr + 0x1C, &numStructs, 2);
    for (int i = 0; i < 2; i++) {
        intChecksum += numStructs;
        numStructs >>= 8;
    }

    proxy.writeBlob(addr + 0x1E,
            &smbiosHeader.intermediateHeader.smbiosBCDRevision, 1);
    intChecksum += smbiosHeader.intermediateHeader.smbiosBCDRevision;

    /*
     * Structure table
     */

    Addr base = smbiosHeader.intermediateHeader.tableAddr;
    Addr offset = 0;
    uint16_t maxSize = 0;
    std::vector<SMBiosStructure *>::iterator it;
    for (it = structures.begin(); it != structures.end(); it++) {
        uint16_t size = (*it)->writeOut(proxy, base + offset);
        if (size > maxSize)
            maxSize = size;
        offset += size;
    }

    structSize = offset;

    /*
     * Header
     */

    maxSize = htole(maxSize);
    proxy.writeBlob(addr + 0x8, &maxSize, 2);
    for (int i = 0; i < 2; i++) {
        mainChecksum += maxSize;
        maxSize >>= 8;
    }

    // Set the checksum
    mainChecksum = -mainChecksum;
    proxy.writeBlob(addr + 0x4, &mainChecksum, 1);

    /*
     * Intermediate header
     */

    uint16_t tableSize = offset;
    tableSize = htole(tableSize);
    proxy.writeBlob(addr + 0x16, &tableSize, 2);
    for (int i = 0; i < 2; i++) {
        intChecksum += tableSize;
        tableSize >>= 8;
    }

    intChecksum = -intChecksum;
    proxy.writeBlob(addr + 0x15, &intChecksum, 1);
}

X86ISA::SMBios::BiosInformation *
X86SMBiosBiosInformationParams::create()
{
    return new X86ISA::SMBios::BiosInformation(this);
}

X86ISA::SMBios::SMBiosTable *
X86SMBiosSMBiosTableParams::create()
{
    return new X86ISA::SMBios::SMBiosTable(this);
}
