/*
 * 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
 *          Miguel Serrano
 */

/** @file
 * Malta I/O including PIC, PIT, RTC, DMA
 */

#include "dev/mips/malta_io.hh"

#include <sys/time.h>

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

#include "base/time.hh"
#include "base/trace.hh"
#include "debug/Malta.hh"
#include "dev/mips/malta.hh"
#include "dev/mips/malta_cchip.hh"
#include "dev/mips/maltareg.h"
#include "dev/rtcreg.h"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
#include "mem/port.hh"
#include "params/MaltaIO.hh"
#include "sim/system.hh"

using namespace std;

MaltaIO::RTC::RTC(const string &name, const MaltaIOParams *p)
    : MC146818(p->malta, name, p->time, p->year_is_bcd, p->frequency),
      malta(p->malta)
{
}

MaltaIO::MaltaIO(const Params *p)
    : BasicPioDevice(p, 0x100), malta(p->malta),
      pitimer(this, p->name + "pitimer"), rtc(p->name + ".rtc", p)
{
    // set the back pointer from malta to myself
    malta->io = this;

    timerData = 0;
    picr = 0;
    picInterrupting = false;
}

Tick
MaltaIO::frequency() const
{
    return SimClock::Frequency / params()->frequency;
}

Tick
MaltaIO::read(PacketPtr pkt)
{
    panic("MaltaIO::read(...) not implemented inside malta_io.cc");
    return pioDelay;
}

Tick
MaltaIO::write(PacketPtr pkt)
{
    panic("MaltaIO::write(...) not implemented inside malta_io.cc");
    return pioDelay;
}

void
MaltaIO::postIntr(uint8_t interrupt)
{
    malta->cchip->postIntr(interrupt);
    DPRINTF(Malta, "posting pic interrupt to cchip\n");
}

void
MaltaIO::clearIntr(uint8_t interrupt)
{
    malta->cchip->clearIntr(interrupt);
    DPRINTF(Malta, "clear pic interrupt to cchip\n");
}

void
MaltaIO::serialize(CheckpointOut &cp) const
{
    SERIALIZE_SCALAR(timerData);
    SERIALIZE_SCALAR(mask1);
    SERIALIZE_SCALAR(mask2);
    SERIALIZE_SCALAR(mode1);
    SERIALIZE_SCALAR(mode2);
    SERIALIZE_SCALAR(picr);
    SERIALIZE_SCALAR(picInterrupting);

    // Serialize the timers
    pitimer.serialize("pitimer", cp);
    rtc.serialize("rtc", cp);
}

void
MaltaIO::unserialize(CheckpointIn &cp)
{
    UNSERIALIZE_SCALAR(timerData);
    UNSERIALIZE_SCALAR(mask1);
    UNSERIALIZE_SCALAR(mask2);
    UNSERIALIZE_SCALAR(mode1);
    UNSERIALIZE_SCALAR(mode2);
    UNSERIALIZE_SCALAR(picr);
    UNSERIALIZE_SCALAR(picInterrupting);

    // Unserialize the timers
    pitimer.unserialize("pitimer", cp);
    rtc.unserialize("rtc", cp);
}

void
MaltaIO::startup()
{
    rtc.startup();
    pitimer.startup();
}

MaltaIO *
MaltaIOParams::create()
{
    return new MaltaIO(this);
}
