/*
 * 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.
 *
 * 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
 */

#ifndef __ARCH_X86_BIOS_INTELMP_HH__
#define __ARCH_X86_BIOS_INTELMP_HH__

#include <string>
#include <vector>

#include "base/bitfield.hh"
#include "enums/X86IntelMPAddressType.hh"
#include "enums/X86IntelMPInterruptType.hh"
#include "enums/X86IntelMPPolarity.hh"
#include "enums/X86IntelMPRangeList.hh"
#include "enums/X86IntelMPTriggerMode.hh"
#include "sim/sim_object.hh"

class PortProxy;

// Config entry types
struct X86IntelMPBaseConfigEntryParams;
struct X86IntelMPExtConfigEntryParams;

// General table structures
struct X86IntelMPConfigTableParams;
struct X86IntelMPFloatingPointerParams;

// Base entry types
struct X86IntelMPBusParams;
struct X86IntelMPIOAPICParams;
struct X86IntelMPIOIntAssignmentParams;
struct X86IntelMPLocalIntAssignmentParams;
struct X86IntelMPProcessorParams;

// Extended entry types
struct X86IntelMPAddrSpaceMappingParams;
struct X86IntelMPBusHierarchyParams;
struct X86IntelMPCompatAddrSpaceModParams;

template<class T>
uint8_t writeOutField(PortProxy& proxy, Addr addr, T val);

uint8_t writeOutString(PortProxy& proxy, Addr addr, std::string str,
                       int length);

namespace X86ISA
{

namespace IntelMP
{

class FloatingPointer : public SimObject
{
  protected:
    typedef X86IntelMPFloatingPointerParams Params;

    uint32_t tableAddr;
    uint8_t specRev;
    uint8_t defaultConfig;
    bool imcrPresent;

    static const char signature[];

  public:

    Addr writeOut(PortProxy& proxy, Addr addr);

    Addr getTableAddr()
    {
        return tableAddr;
    }

    void setTableAddr(Addr addr)
    {
        tableAddr = addr;
    }

    FloatingPointer(Params * p);
};

class BaseConfigEntry : public SimObject
{
  protected:
    typedef X86IntelMPBaseConfigEntryParams Params;

    uint8_t type;

  public:

    virtual Addr writeOut(PortProxy& proxy, Addr addr, uint8_t &checkSum);

    BaseConfigEntry(Params * p, uint8_t _type);
};

class ExtConfigEntry : public SimObject
{
  protected:
    typedef X86IntelMPExtConfigEntryParams Params;

    uint8_t type;
    uint8_t length;

  public:

    virtual Addr writeOut(PortProxy& proxy, Addr addr, uint8_t &checkSum);

    ExtConfigEntry(Params * p, uint8_t _type, uint8_t _length);
};

class ConfigTable : public SimObject
{
  protected:
    typedef X86IntelMPConfigTableParams Params;

    static const char signature[];

    uint8_t specRev;
    std::string oemID;
    std::string productID;
    uint32_t oemTableAddr;
    uint16_t oemTableSize;
    uint32_t localApic;

    std::vector<BaseConfigEntry *> baseEntries;
    std::vector<ExtConfigEntry *> extEntries;

  public:
    Addr writeOut(PortProxy& proxy, Addr addr);

    ConfigTable(Params * p);
};

class Processor : public BaseConfigEntry
{
  protected:
    typedef X86IntelMPProcessorParams Params;

    uint8_t localApicID;
    uint8_t localApicVersion;
    uint8_t cpuFlags;
    uint32_t cpuSignature;
    uint32_t featureFlags;

  public:
    Addr writeOut(PortProxy& proxy, Addr addr, uint8_t &checkSum);

    Processor(Params * p);
};

class Bus : public BaseConfigEntry
{
  protected:
    typedef X86IntelMPBusParams Params;

    uint8_t busID;
    std::string busType;

  public:
    Addr writeOut(PortProxy& proxy, Addr addr, uint8_t &checkSum);

    Bus(Params * p);
};

class IOAPIC : public BaseConfigEntry
{
  protected:
    typedef X86IntelMPIOAPICParams Params;

    uint8_t id;
    uint8_t version;
    uint8_t flags;
    uint32_t address;

  public:
    Addr writeOut(PortProxy& proxy, Addr addr, uint8_t &checkSum);

    IOAPIC(Params * p);
};

class IntAssignment : public BaseConfigEntry
{
  protected:
    uint8_t interruptType;

    uint16_t flags;

    uint8_t sourceBusID;
    uint8_t sourceBusIRQ;

    uint8_t destApicID;
    uint8_t destApicIntIn;

  public:
    Addr writeOut(PortProxy& proxy, Addr addr, uint8_t &checkSum);

    IntAssignment(X86IntelMPBaseConfigEntryParams * p,
            Enums::X86IntelMPInterruptType _interruptType,
            Enums::X86IntelMPPolarity polarity,
            Enums::X86IntelMPTriggerMode trigger,
            uint8_t _type,
            uint8_t _sourceBusID, uint8_t _sourceBusIRQ,
            uint8_t _destApicID, uint8_t _destApicIntIn) :
        BaseConfigEntry(p, _type),
        interruptType(_interruptType), flags(0),
        sourceBusID(_sourceBusID), sourceBusIRQ(_sourceBusIRQ),
        destApicID(_destApicID), destApicIntIn(_destApicIntIn)
    {
        replaceBits(flags, 0, 1, polarity);
        replaceBits(flags, 2, 3, trigger);
    }
};

class IOIntAssignment : public IntAssignment
{
  protected:
    typedef X86IntelMPIOIntAssignmentParams Params;

  public:
    IOIntAssignment(Params * p);
};

class LocalIntAssignment : public IntAssignment
{
  protected:
    typedef X86IntelMPLocalIntAssignmentParams Params;

  public:
    LocalIntAssignment(Params * p);
};

class AddrSpaceMapping : public ExtConfigEntry
{
  protected:
    typedef X86IntelMPAddrSpaceMappingParams Params;

    uint8_t busID;
    uint8_t addrType;
    uint64_t addr;
    uint64_t addrLength;

  public:
    Addr writeOut(PortProxy& proxy, Addr addr, uint8_t &checkSum);

    AddrSpaceMapping(Params * p);
};

class BusHierarchy : public ExtConfigEntry
{
  protected:
    typedef X86IntelMPBusHierarchyParams Params;

    uint8_t busID;
    uint8_t info;
    uint8_t parentBus;

  public:
    Addr writeOut(PortProxy& proxy, Addr addr, uint8_t &checkSum);

    BusHierarchy(Params * p);
};

class CompatAddrSpaceMod : public ExtConfigEntry
{
  protected:
    typedef X86IntelMPCompatAddrSpaceModParams Params;

    uint8_t busID;
    uint8_t mod;
    uint32_t rangeList;

  public:
    Addr writeOut(PortProxy& proxy, Addr addr, uint8_t &checkSum);

    CompatAddrSpaceMod(Params * p);
};

} //IntelMP

} //X86ISA

#endif
