/*
 * Copyright (c) 2004-2005 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: Ali Saidi
 *          Andrew Schultz
 */

/** @file
 * Tsunami PChip (pci)
 */
#include "dev/alpha/tsunami_pchip.hh"

#include <deque>
#include <string>
#include <vector>

#include "base/trace.hh"
#include "config/the_isa.hh"
#include "debug/Tsunami.hh"
#include "dev/alpha/tsunami.hh"
#include "dev/alpha/tsunami_cchip.hh"
#include "dev/alpha/tsunamireg.h"
#include "dev/pci/device.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
#include "sim/system.hh"

using namespace std;
//Should this be AlphaISA?
using namespace TheISA;

TsunamiPChip::TsunamiPChip(const Params *p)
    : GenericPciHost(p),
      pioRange(RangeSize(p->pio_addr, 0x1000)),
      pioDelay(p->pio_latency)
{
    for (int i = 0; i < 4; i++) {
        wsba[i] = 0;
        wsm[i] = 0;
        tba[i] = 0;
    }

    // initialize pchip control register
    pctl = (ULL(0x1) << 20) | (ULL(0x1) << 32) | (ULL(0x2) << 36);

    //Set back pointer in tsunami
    p->tsunami->pchip = this;
}

Tick
TsunamiPChip::read(PacketPtr pkt)
{
    // We only need to handle our own configuration registers, pass
    // unknown addresses to the generic code.
    if (!pioRange.contains(pkt->getAddr()))
        return GenericPciHost::read(pkt);

    Addr daddr = (pkt->getAddr() - pioRange.start()) >> 6;;
    assert(pkt->getSize() == sizeof(uint64_t));


    DPRINTF(Tsunami, "read  va=%#x size=%d\n", pkt->getAddr(), pkt->getSize());

    switch(daddr) {
      case TSDEV_PC_WSBA0:
            pkt->setLE(wsba[0]);
            break;
      case TSDEV_PC_WSBA1:
            pkt->setLE(wsba[1]);
            break;
      case TSDEV_PC_WSBA2:
            pkt->setLE(wsba[2]);
            break;
      case TSDEV_PC_WSBA3:
            pkt->setLE(wsba[3]);
            break;
      case TSDEV_PC_WSM0:
            pkt->setLE(wsm[0]);
            break;
      case TSDEV_PC_WSM1:
            pkt->setLE(wsm[1]);
            break;
      case TSDEV_PC_WSM2:
            pkt->setLE(wsm[2]);
            break;
      case TSDEV_PC_WSM3:
            pkt->setLE(wsm[3]);
            break;
      case TSDEV_PC_TBA0:
            pkt->setLE(tba[0]);
            break;
      case TSDEV_PC_TBA1:
            pkt->setLE(tba[1]);
            break;
      case TSDEV_PC_TBA2:
            pkt->setLE(tba[2]);
            break;
      case TSDEV_PC_TBA3:
            pkt->setLE(tba[3]);
            break;
      case TSDEV_PC_PCTL:
            pkt->setLE(pctl);
            break;
      case TSDEV_PC_PLAT:
            panic("PC_PLAT not implemented\n");
      case TSDEV_PC_RES:
            panic("PC_RES not implemented\n");
      case TSDEV_PC_PERROR:
            pkt->setLE((uint64_t)0x00);
            break;
      case TSDEV_PC_PERRMASK:
            pkt->setLE((uint64_t)0x00);
            break;
      case TSDEV_PC_PERRSET:
            panic("PC_PERRSET not implemented\n");
      case TSDEV_PC_TLBIV:
            panic("PC_TLBIV not implemented\n");
      case TSDEV_PC_TLBIA:
            pkt->setLE((uint64_t)0x00); // shouldn't be readable, but linux
            break;
      case TSDEV_PC_PMONCTL:
            panic("PC_PMONCTL not implemented\n");
      case TSDEV_PC_PMONCNT:
            panic("PC_PMONCTN not implemented\n");
      default:
          panic("Default in PChip Read reached reading 0x%x\n", daddr);
    }

    pkt->makeAtomicResponse();
    return pioDelay;

}

Tick
TsunamiPChip::write(PacketPtr pkt)
{
    // We only need to handle our own configuration registers, pass
    // unknown addresses to the generic code.
    if (!pioRange.contains(pkt->getAddr()))
        return GenericPciHost::write(pkt);

    Addr daddr = (pkt->getAddr() - pioRange.start()) >> 6;

    assert(pkt->getSize() == sizeof(uint64_t));

    DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt->getAddr(), pkt->getSize());

    switch(daddr) {
        case TSDEV_PC_WSBA0:
              wsba[0] = pkt->getLE<uint64_t>();
              break;
        case TSDEV_PC_WSBA1:
              wsba[1] = pkt->getLE<uint64_t>();
              break;
        case TSDEV_PC_WSBA2:
              wsba[2] = pkt->getLE<uint64_t>();
              break;
        case TSDEV_PC_WSBA3:
              wsba[3] = pkt->getLE<uint64_t>();
              break;
        case TSDEV_PC_WSM0:
              wsm[0] = pkt->getLE<uint64_t>();
              break;
        case TSDEV_PC_WSM1:
              wsm[1] = pkt->getLE<uint64_t>();
              break;
        case TSDEV_PC_WSM2:
              wsm[2] = pkt->getLE<uint64_t>();
              break;
        case TSDEV_PC_WSM3:
              wsm[3] = pkt->getLE<uint64_t>();
              break;
        case TSDEV_PC_TBA0:
              tba[0] = pkt->getLE<uint64_t>();
              break;
        case TSDEV_PC_TBA1:
              tba[1] = pkt->getLE<uint64_t>();
              break;
        case TSDEV_PC_TBA2:
              tba[2] = pkt->getLE<uint64_t>();
              break;
        case TSDEV_PC_TBA3:
              tba[3] = pkt->getLE<uint64_t>();
              break;
        case TSDEV_PC_PCTL:
              pctl = pkt->getLE<uint64_t>();
              break;
        case TSDEV_PC_PLAT:
              panic("PC_PLAT not implemented\n");
        case TSDEV_PC_RES:
              panic("PC_RES not implemented\n");
        case TSDEV_PC_PERROR:
              break;
        case TSDEV_PC_PERRMASK:
              panic("PC_PERRMASK not implemented\n");
        case TSDEV_PC_PERRSET:
              panic("PC_PERRSET not implemented\n");
        case TSDEV_PC_TLBIV:
              panic("PC_TLBIV not implemented\n");
        case TSDEV_PC_TLBIA:
              break; // value ignored, supposted to invalidate SG TLB
        case TSDEV_PC_PMONCTL:
              panic("PC_PMONCTL not implemented\n");
        case TSDEV_PC_PMONCNT:
              panic("PC_PMONCTN not implemented\n");
        default:
            panic("Default in PChip write reached reading 0x%x\n", daddr);

    } // uint64_t

    pkt->makeAtomicResponse();
    return pioDelay;
}


AddrRangeList
TsunamiPChip::getAddrRanges() const
{
    return AddrRangeList({
            RangeSize(confBase, confSize),
            pioRange
        });
}


#define DMA_ADDR_MASK ULL(0x3ffffffff)

Addr
TsunamiPChip::dmaAddr(const PciBusAddr &dev, Addr busAddr) const
{
    // compare the address to the window base registers
    uint64_t tbaMask = 0;
    uint64_t baMask = 0;

    uint64_t windowMask = 0;
    uint64_t windowBase = 0;

    uint64_t pteEntry = 0;

    Addr pteAddr;
    Addr dmaAddr;

#if 0
    DPRINTF(IdeDisk, "Translation for bus address: %#x\n", busAddr);
    for (int i = 0; i < 4; i++) {
        DPRINTF(IdeDisk, "(%d) base:%#x mask:%#x\n",
                i, wsba[i], wsm[i]);

        windowBase = wsba[i];
        windowMask = ~wsm[i] & (ULL(0xfff) << 20);

        if ((busAddr & windowMask) == (windowBase & windowMask)) {
            DPRINTF(IdeDisk, "Would have matched %d (wb:%#x wm:%#x --> ba&wm:%#x wb&wm:%#x)\n",
                    i, windowBase, windowMask, (busAddr & windowMask),
                    (windowBase & windowMask));
        }
    }
#endif

    for (int i = 0; i < 4; i++) {

        windowBase = wsba[i];
        windowMask = ~wsm[i] & (ULL(0xfff) << 20);

        if ((busAddr & windowMask) == (windowBase & windowMask)) {

            if (wsba[i] & 0x1) {   // see if enabled
                if (wsba[i] & 0x2) { // see if SG bit is set
                    /** @todo
                        This currently is faked by just doing a direct
                        read from memory, however, to be realistic, this
                        needs to actually do a bus transaction.  The process
                        is explained in the tsunami documentation on page
                        10-12 and basically munges the address to look up a
                        PTE from a table in memory and then uses that mapping
                        to create an address for the SG page
                    */

                    tbaMask = ~(((wsm[i] & (ULL(0xfff) << 20)) >> 10) | ULL(0x3ff));
                    baMask = (wsm[i] & (ULL(0xfff) << 20)) | (ULL(0x7f) << 13);
                    pteAddr = (tba[i] & tbaMask) | ((busAddr & baMask) >> 10);

                    sys->physProxy.readBlob(pteAddr, (uint8_t*)&pteEntry,
                                            sizeof(uint64_t));

                    dmaAddr = ((pteEntry & ~ULL(0x1)) << 12) | (busAddr & ULL(0x1fff));

                } else {
                    baMask = (wsm[i] & (ULL(0xfff) << 20)) | ULL(0xfffff);
                    tbaMask = ~baMask;
                    dmaAddr = (tba[i] & tbaMask) | (busAddr & baMask);
                }

                return (dmaAddr & DMA_ADDR_MASK);
            }
        }
    }

    // if no match was found, then return the original address
    return busAddr;
}

void
TsunamiPChip::serialize(CheckpointOut &cp) const
{
    SERIALIZE_SCALAR(pctl);
    SERIALIZE_ARRAY(wsba, 4);
    SERIALIZE_ARRAY(wsm, 4);
    SERIALIZE_ARRAY(tba, 4);
}

void
TsunamiPChip::unserialize(CheckpointIn &cp)
{
    UNSERIALIZE_SCALAR(pctl);
    UNSERIALIZE_ARRAY(wsba, 4);
    UNSERIALIZE_ARRAY(wsm, 4);
    UNSERIALIZE_ARRAY(tba, 4);
}


TsunamiPChip *
TsunamiPChipParams::create()
{
    return new TsunamiPChip(this);
}
