15392Sgblack@eecs.umich.edu/*
25392Sgblack@eecs.umich.edu * Copyright (c) 2004-2005 The Regents of The University of Michigan
35392Sgblack@eecs.umich.edu * All rights reserved.
45392Sgblack@eecs.umich.edu *
55392Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
65392Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
75392Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
85392Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
95392Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
105392Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
115392Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
125392Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
135392Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
145392Sgblack@eecs.umich.edu * this software without specific prior written permission.
155392Sgblack@eecs.umich.edu *
165392Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
175392Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
185392Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
195392Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
205392Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
215392Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
225392Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235392Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
245392Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255392Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
265392Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275392Sgblack@eecs.umich.edu *
285392Sgblack@eecs.umich.edu * Authors: Ali Saidi
295392Sgblack@eecs.umich.edu *          Andrew Schultz
305392Sgblack@eecs.umich.edu *          Miguel Serrano
315392Sgblack@eecs.umich.edu */
325392Sgblack@eecs.umich.edu
3311793Sbrandon.potter@amd.com#include "dev/mc146818.hh"
3411793Sbrandon.potter@amd.com
355392Sgblack@eecs.umich.edu#include <sys/time.h>
365392Sgblack@eecs.umich.edu
378229Snate@binkert.org#include <ctime>
385392Sgblack@eecs.umich.edu#include <string>
395392Sgblack@eecs.umich.edu
405813Sgblack@eecs.umich.edu#include "base/bitfield.hh"
415392Sgblack@eecs.umich.edu#include "base/time.hh"
425392Sgblack@eecs.umich.edu#include "base/trace.hh"
438232Snate@binkert.org#include "debug/MC146818.hh"
445392Sgblack@eecs.umich.edu#include "dev/rtcreg.h"
455392Sgblack@eecs.umich.edu
465392Sgblack@eecs.umich.eduusing namespace std;
475392Sgblack@eecs.umich.edu
486620Sgblack@eecs.umich.edustatic uint8_t
496620Sgblack@eecs.umich.edubcdize(uint8_t val)
505392Sgblack@eecs.umich.edu{
516620Sgblack@eecs.umich.edu    uint8_t result;
526620Sgblack@eecs.umich.edu    result = val % 10;
536620Sgblack@eecs.umich.edu    result += (val / 10) << 4;
546620Sgblack@eecs.umich.edu    return result;
556620Sgblack@eecs.umich.edu}
565392Sgblack@eecs.umich.edu
576621Sgblack@eecs.umich.edustatic uint8_t
586621Sgblack@eecs.umich.eduunbcdize(uint8_t val)
596621Sgblack@eecs.umich.edu{
606621Sgblack@eecs.umich.edu    uint8_t result;
616621Sgblack@eecs.umich.edu    result = val & 0xf;
626621Sgblack@eecs.umich.edu    result += (val >> 4) * 10;
636621Sgblack@eecs.umich.edu    return result;
646621Sgblack@eecs.umich.edu}
656621Sgblack@eecs.umich.edu
666620Sgblack@eecs.umich.eduvoid
676620Sgblack@eecs.umich.eduMC146818::setTime(const struct tm time)
686620Sgblack@eecs.umich.edu{
696620Sgblack@eecs.umich.edu    curTime = time;
705392Sgblack@eecs.umich.edu    year = time.tm_year;
715392Sgblack@eecs.umich.edu    // Unix is 0-11 for month, data seet says start at 1
725392Sgblack@eecs.umich.edu    mon = time.tm_mon + 1;
735392Sgblack@eecs.umich.edu    mday = time.tm_mday;
745392Sgblack@eecs.umich.edu    hour = time.tm_hour;
755392Sgblack@eecs.umich.edu    min = time.tm_min;
765392Sgblack@eecs.umich.edu    sec = time.tm_sec;
775392Sgblack@eecs.umich.edu
785392Sgblack@eecs.umich.edu    // Datasheet says 1 is sunday
795392Sgblack@eecs.umich.edu    wday = time.tm_wday + 1;
805392Sgblack@eecs.umich.edu
819730Sandreas@sandberg.pp.se    if (!stat_regB.dm) {
826620Sgblack@eecs.umich.edu        // The datasheet says that the year field can be either BCD or
836620Sgblack@eecs.umich.edu        // years since 1900.  Linux seems to be happy with years since
846620Sgblack@eecs.umich.edu        // 1900.
856620Sgblack@eecs.umich.edu        year = bcdize(year % 100);
866620Sgblack@eecs.umich.edu        mon = bcdize(mon);
876620Sgblack@eecs.umich.edu        mday = bcdize(mday);
886620Sgblack@eecs.umich.edu        hour = bcdize(hour);
896620Sgblack@eecs.umich.edu        min = bcdize(min);
906620Sgblack@eecs.umich.edu        sec = bcdize(sec);
916620Sgblack@eecs.umich.edu    }
926620Sgblack@eecs.umich.edu}
936620Sgblack@eecs.umich.edu
946620Sgblack@eecs.umich.eduMC146818::MC146818(EventManager *em, const string &n, const struct tm time,
956620Sgblack@eecs.umich.edu                   bool bcd, Tick frequency)
966620Sgblack@eecs.umich.edu    : EventManager(em), _name(n), event(this, frequency), tickEvent(this)
976620Sgblack@eecs.umich.edu{
986620Sgblack@eecs.umich.edu    memset(clock_data, 0, sizeof(clock_data));
999730Sandreas@sandberg.pp.se
1009730Sandreas@sandberg.pp.se    stat_regA = 0;
1019730Sandreas@sandberg.pp.se    stat_regA.dv = RTCA_DV_32768HZ;
1029730Sandreas@sandberg.pp.se    stat_regA.rs = RTCA_RS_1024HZ;
1039730Sandreas@sandberg.pp.se
1049730Sandreas@sandberg.pp.se    stat_regB = 0;
1059730Sandreas@sandberg.pp.se    stat_regB.pie = 1;
1069730Sandreas@sandberg.pp.se    stat_regB.format24h = 1;
1079730Sandreas@sandberg.pp.se    stat_regB.dm = bcd ? 0 : 1;
1086620Sgblack@eecs.umich.edu
1096620Sgblack@eecs.umich.edu    setTime(time);
1105392Sgblack@eecs.umich.edu    DPRINTFN("Real-time clock set to %s", asctime(&time));
1115392Sgblack@eecs.umich.edu}
1125392Sgblack@eecs.umich.edu
1135606Snate@binkert.orgMC146818::~MC146818()
1145606Snate@binkert.org{
1157683Ssteve.reinhardt@amd.com    deschedule(tickEvent);
1167683Ssteve.reinhardt@amd.com    deschedule(event);
1175606Snate@binkert.org}
1185606Snate@binkert.org
1199730Sandreas@sandberg.pp.sebool
1209730Sandreas@sandberg.pp.seMC146818::rega_dv_disabled(const RtcRegA &reg)
1219730Sandreas@sandberg.pp.se{
1229730Sandreas@sandberg.pp.se    return reg.dv == RTCA_DV_DISABLED0 ||
1239730Sandreas@sandberg.pp.se        reg.dv == RTCA_DV_DISABLED1;
1249730Sandreas@sandberg.pp.se}
1259730Sandreas@sandberg.pp.se
1265392Sgblack@eecs.umich.eduvoid
12710631Scdirik@micron.comMC146818::startup()
12810631Scdirik@micron.com{
12910631Scdirik@micron.com    assert(!event.scheduled());
13010631Scdirik@micron.com    assert(!tickEvent.scheduled());
13110777Snikos.nikoleris@gmail.com
13210777Snikos.nikoleris@gmail.com    if (stat_regB.pie)
13310777Snikos.nikoleris@gmail.com        schedule(event, curTick() + event.offset);
13410777Snikos.nikoleris@gmail.com    if (!rega_dv_disabled(stat_regA))
13510777Snikos.nikoleris@gmail.com        schedule(tickEvent, curTick() + tickEvent.offset);
13610631Scdirik@micron.com}
13710631Scdirik@micron.com
13810631Scdirik@micron.comvoid
1395392Sgblack@eecs.umich.eduMC146818::writeData(const uint8_t addr, const uint8_t data)
1405392Sgblack@eecs.umich.edu{
1419730Sandreas@sandberg.pp.se    bool panic_unsupported(false);
1429730Sandreas@sandberg.pp.se
1436621Sgblack@eecs.umich.edu    if (addr < RTC_STAT_REGA) {
1445392Sgblack@eecs.umich.edu        clock_data[addr] = data;
1456621Sgblack@eecs.umich.edu        curTime.tm_sec = unbcdize(sec);
1466621Sgblack@eecs.umich.edu        curTime.tm_min = unbcdize(min);
1476621Sgblack@eecs.umich.edu        curTime.tm_hour = unbcdize(hour);
1486621Sgblack@eecs.umich.edu        curTime.tm_mday = unbcdize(mday);
1496621Sgblack@eecs.umich.edu        curTime.tm_mon = unbcdize(mon) - 1;
1506621Sgblack@eecs.umich.edu        curTime.tm_year = ((unbcdize(year) + 50) % 100) + 1950;
1516621Sgblack@eecs.umich.edu        curTime.tm_wday = unbcdize(wday) - 1;
1526621Sgblack@eecs.umich.edu    } else {
1535392Sgblack@eecs.umich.edu        switch (addr) {
1549730Sandreas@sandberg.pp.se          case RTC_STAT_REGA: {
1559730Sandreas@sandberg.pp.se              RtcRegA old_rega(stat_regA);
1569730Sandreas@sandberg.pp.se              stat_regA = data;
1579730Sandreas@sandberg.pp.se              // The "update in progress" bit is read only.
1589730Sandreas@sandberg.pp.se              stat_regA.uip = old_rega;
1599730Sandreas@sandberg.pp.se
1609731Sandreas@sandberg.pp.se              if (!rega_dv_disabled(stat_regA) &&
1619731Sandreas@sandberg.pp.se                  stat_regA.dv != RTCA_DV_32768HZ) {
1629730Sandreas@sandberg.pp.se                  inform("RTC: Unimplemented divider configuration: %i\n",
1639730Sandreas@sandberg.pp.se                        stat_regA.dv);
1649730Sandreas@sandberg.pp.se                  panic_unsupported = true;
1659730Sandreas@sandberg.pp.se              }
1669730Sandreas@sandberg.pp.se
1679730Sandreas@sandberg.pp.se              if (stat_regA.rs != RTCA_RS_1024HZ) {
1689730Sandreas@sandberg.pp.se                  inform("RTC: Unimplemented interrupt rate: %i\n",
1699730Sandreas@sandberg.pp.se                        stat_regA.rs);
1709730Sandreas@sandberg.pp.se                  panic_unsupported = true;
1719730Sandreas@sandberg.pp.se              }
1729731Sandreas@sandberg.pp.se
1739731Sandreas@sandberg.pp.se              if (rega_dv_disabled(stat_regA)) {
1749731Sandreas@sandberg.pp.se                  // The divider is disabled, make sure that we don't
1759731Sandreas@sandberg.pp.se                  // schedule any ticks.
1769731Sandreas@sandberg.pp.se                  if (tickEvent.scheduled())
1779731Sandreas@sandberg.pp.se                      deschedule(tickEvent);
1789731Sandreas@sandberg.pp.se              } else if (rega_dv_disabled(old_rega))  {
1799739Sandreas@sandberg.pp.se                  // According to the specification, the next tick
1809739Sandreas@sandberg.pp.se                  // happens after 0.5s when the divider chain goes
1819739Sandreas@sandberg.pp.se                  // from reset to active. So, we simply schedule the
1829739Sandreas@sandberg.pp.se                  // tick after 0.5s.
1839731Sandreas@sandberg.pp.se                  assert(!tickEvent.scheduled());
1849731Sandreas@sandberg.pp.se                  schedule(tickEvent, curTick() + SimClock::Int::s / 2);
1859731Sandreas@sandberg.pp.se              }
1869730Sandreas@sandberg.pp.se          } break;
1875392Sgblack@eecs.umich.edu          case RTC_STAT_REGB:
1889730Sandreas@sandberg.pp.se            stat_regB = data;
1899730Sandreas@sandberg.pp.se            if (stat_regB.aie || stat_regB.uie) {
1909730Sandreas@sandberg.pp.se                inform("RTC: Unimplemented interrupt configuration: %s %s\n",
1919730Sandreas@sandberg.pp.se                      stat_regB.aie ? "alarm" : "",
1929730Sandreas@sandberg.pp.se                      stat_regB.uie ? "update" : "");
1939730Sandreas@sandberg.pp.se                panic_unsupported = true;
1949730Sandreas@sandberg.pp.se            }
1959730Sandreas@sandberg.pp.se
1969730Sandreas@sandberg.pp.se            if (stat_regB.dm) {
1979730Sandreas@sandberg.pp.se                inform("RTC: The binary interface is not fully implemented.\n");
1989730Sandreas@sandberg.pp.se                panic_unsupported = true;
1999730Sandreas@sandberg.pp.se            }
2009730Sandreas@sandberg.pp.se
2019730Sandreas@sandberg.pp.se            if (!stat_regB.format24h) {
2029730Sandreas@sandberg.pp.se                inform("RTC: The 12h time format not supported.\n");
2039730Sandreas@sandberg.pp.se                panic_unsupported = true;
2049730Sandreas@sandberg.pp.se            }
2059730Sandreas@sandberg.pp.se
2069730Sandreas@sandberg.pp.se            if (stat_regB.dse) {
2079730Sandreas@sandberg.pp.se                inform("RTC: Automatic daylight saving time not supported.\n");
2089730Sandreas@sandberg.pp.se                panic_unsupported = true;
2099730Sandreas@sandberg.pp.se            }
2109730Sandreas@sandberg.pp.se
2119730Sandreas@sandberg.pp.se            if (stat_regB.pie) {
2125392Sgblack@eecs.umich.edu                if (!event.scheduled())
2135392Sgblack@eecs.umich.edu                    event.scheduleIntr();
2145392Sgblack@eecs.umich.edu            } else {
2155392Sgblack@eecs.umich.edu                if (event.scheduled())
2165606Snate@binkert.org                    deschedule(event);
2175392Sgblack@eecs.umich.edu            }
2185392Sgblack@eecs.umich.edu            break;
2195392Sgblack@eecs.umich.edu          case RTC_STAT_REGC:
2205392Sgblack@eecs.umich.edu          case RTC_STAT_REGD:
2215392Sgblack@eecs.umich.edu            panic("RTC status registers C and D are not implemented.\n");
2225392Sgblack@eecs.umich.edu            break;
2235392Sgblack@eecs.umich.edu        }
2245392Sgblack@eecs.umich.edu    }
2259730Sandreas@sandberg.pp.se
2269730Sandreas@sandberg.pp.se    if (panic_unsupported)
2279730Sandreas@sandberg.pp.se        panic("Unimplemented RTC configuration!\n");
2289730Sandreas@sandberg.pp.se
2295392Sgblack@eecs.umich.edu}
2305392Sgblack@eecs.umich.edu
2315392Sgblack@eecs.umich.eduuint8_t
2325392Sgblack@eecs.umich.eduMC146818::readData(uint8_t addr)
2335392Sgblack@eecs.umich.edu{
2345392Sgblack@eecs.umich.edu    if (addr < RTC_STAT_REGA)
2355392Sgblack@eecs.umich.edu        return clock_data[addr];
2365392Sgblack@eecs.umich.edu    else {
2375392Sgblack@eecs.umich.edu        switch (addr) {
2385392Sgblack@eecs.umich.edu          case RTC_STAT_REGA:
2395392Sgblack@eecs.umich.edu            // toggle UIP bit for linux
2409730Sandreas@sandberg.pp.se            stat_regA.uip = !stat_regA.uip;
2415392Sgblack@eecs.umich.edu            return stat_regA;
2425392Sgblack@eecs.umich.edu            break;
2435392Sgblack@eecs.umich.edu          case RTC_STAT_REGB:
2445392Sgblack@eecs.umich.edu            return stat_regB;
2455392Sgblack@eecs.umich.edu            break;
2465392Sgblack@eecs.umich.edu          case RTC_STAT_REGC:
2475392Sgblack@eecs.umich.edu          case RTC_STAT_REGD:
2485392Sgblack@eecs.umich.edu            return 0x00;
2495392Sgblack@eecs.umich.edu            break;
2505392Sgblack@eecs.umich.edu          default:
2515392Sgblack@eecs.umich.edu            panic("Shouldn't be here");
2525392Sgblack@eecs.umich.edu        }
2535392Sgblack@eecs.umich.edu    }
2545392Sgblack@eecs.umich.edu}
2555392Sgblack@eecs.umich.edu
2566620Sgblack@eecs.umich.eduvoid
2576620Sgblack@eecs.umich.eduMC146818::tickClock()
2586620Sgblack@eecs.umich.edu{
2599731Sandreas@sandberg.pp.se    assert(!rega_dv_disabled(stat_regA));
2609731Sandreas@sandberg.pp.se
2619730Sandreas@sandberg.pp.se    if (stat_regB.set)
2626620Sgblack@eecs.umich.edu        return;
2636620Sgblack@eecs.umich.edu    time_t calTime = mkutctime(&curTime);
2646620Sgblack@eecs.umich.edu    calTime++;
2656620Sgblack@eecs.umich.edu    setTime(*gmtime(&calTime));
2666620Sgblack@eecs.umich.edu}
2676620Sgblack@eecs.umich.edu
2685392Sgblack@eecs.umich.eduvoid
26910905Sandreas.sandberg@arm.comMC146818::serialize(const string &base, CheckpointOut &cp) const
2705392Sgblack@eecs.umich.edu{
2719730Sandreas@sandberg.pp.se    uint8_t regA_serial(stat_regA);
2729730Sandreas@sandberg.pp.se    uint8_t regB_serial(stat_regB);
2739730Sandreas@sandberg.pp.se
27410905Sandreas.sandberg@arm.com    arrayParamOut(cp, base + ".clock_data", clock_data, sizeof(clock_data));
27510905Sandreas.sandberg@arm.com    paramOut(cp, base + ".stat_regA", (uint8_t)regA_serial);
27610905Sandreas.sandberg@arm.com    paramOut(cp, base + ".stat_regB", (uint8_t)regB_serial);
2776677SBrad.Beckmann@amd.com
2786677SBrad.Beckmann@amd.com    //
27911320Ssteve.reinhardt@amd.com    // save the timer tick and rtc clock tick values to correctly reschedule
2806677SBrad.Beckmann@amd.com    // them during unserialize
2816677SBrad.Beckmann@amd.com    //
2827823Ssteve.reinhardt@amd.com    Tick rtcTimerInterruptTickOffset = event.when() - curTick();
2836677SBrad.Beckmann@amd.com    SERIALIZE_SCALAR(rtcTimerInterruptTickOffset);
2848593Snilay@cs.wisc.edu    Tick rtcClockTickOffset = tickEvent.when() - curTick();
2856677SBrad.Beckmann@amd.com    SERIALIZE_SCALAR(rtcClockTickOffset);
2865392Sgblack@eecs.umich.edu}
2875392Sgblack@eecs.umich.edu
2885392Sgblack@eecs.umich.eduvoid
28910905Sandreas.sandberg@arm.comMC146818::unserialize(const string &base, CheckpointIn &cp)
2905392Sgblack@eecs.umich.edu{
2919730Sandreas@sandberg.pp.se    uint8_t tmp8;
2929730Sandreas@sandberg.pp.se
29310905Sandreas.sandberg@arm.com    arrayParamIn(cp, base + ".clock_data", clock_data,
2945392Sgblack@eecs.umich.edu                 sizeof(clock_data));
2959730Sandreas@sandberg.pp.se
29610905Sandreas.sandberg@arm.com    paramIn(cp, base + ".stat_regA", tmp8);
2979730Sandreas@sandberg.pp.se    stat_regA = tmp8;
29810905Sandreas.sandberg@arm.com    paramIn(cp, base + ".stat_regB", tmp8);
2999730Sandreas@sandberg.pp.se    stat_regB = tmp8;
3005392Sgblack@eecs.umich.edu
3016677SBrad.Beckmann@amd.com    //
3026677SBrad.Beckmann@amd.com    // properly schedule the timer and rtc clock events
3036677SBrad.Beckmann@amd.com    //
3046677SBrad.Beckmann@amd.com    Tick rtcTimerInterruptTickOffset;
3056677SBrad.Beckmann@amd.com    UNSERIALIZE_SCALAR(rtcTimerInterruptTickOffset);
30610631Scdirik@micron.com    event.offset = rtcTimerInterruptTickOffset;
3076677SBrad.Beckmann@amd.com    Tick rtcClockTickOffset;
3086677SBrad.Beckmann@amd.com    UNSERIALIZE_SCALAR(rtcClockTickOffset);
30910631Scdirik@micron.com    tickEvent.offset = rtcClockTickOffset;
3105392Sgblack@eecs.umich.edu}
3115392Sgblack@eecs.umich.edu
3125392Sgblack@eecs.umich.eduMC146818::RTCEvent::RTCEvent(MC146818 * _parent, Tick i)
31310631Scdirik@micron.com    : parent(_parent), interval(i), offset(i)
3145392Sgblack@eecs.umich.edu{
3155392Sgblack@eecs.umich.edu    DPRINTF(MC146818, "RTC Event Initilizing\n");
3165392Sgblack@eecs.umich.edu}
3175392Sgblack@eecs.umich.edu
3185392Sgblack@eecs.umich.eduvoid
3195392Sgblack@eecs.umich.eduMC146818::RTCEvent::scheduleIntr()
3205392Sgblack@eecs.umich.edu{
3217823Ssteve.reinhardt@amd.com    parent->schedule(this, curTick() + interval);
3225392Sgblack@eecs.umich.edu}
3235392Sgblack@eecs.umich.edu
3245392Sgblack@eecs.umich.eduvoid
3255392Sgblack@eecs.umich.eduMC146818::RTCEvent::process()
3265392Sgblack@eecs.umich.edu{
3275392Sgblack@eecs.umich.edu    DPRINTF(MC146818, "RTC Timer Interrupt\n");
3287823Ssteve.reinhardt@amd.com    parent->schedule(this, curTick() + interval);
3295392Sgblack@eecs.umich.edu    parent->handleEvent();
3305392Sgblack@eecs.umich.edu}
3315392Sgblack@eecs.umich.edu
3325392Sgblack@eecs.umich.educonst char *
3335392Sgblack@eecs.umich.eduMC146818::RTCEvent::description() const
3345392Sgblack@eecs.umich.edu{
3355392Sgblack@eecs.umich.edu    return "RTC interrupt";
3365392Sgblack@eecs.umich.edu}
3376620Sgblack@eecs.umich.edu
3386620Sgblack@eecs.umich.eduvoid
3396620Sgblack@eecs.umich.eduMC146818::RTCTickEvent::process()
3406620Sgblack@eecs.umich.edu{
3416620Sgblack@eecs.umich.edu    DPRINTF(MC146818, "RTC clock tick\n");
3427823Ssteve.reinhardt@amd.com    parent->schedule(this, curTick() + SimClock::Int::s);
3436620Sgblack@eecs.umich.edu    parent->tickClock();
3446620Sgblack@eecs.umich.edu}
3456620Sgblack@eecs.umich.edu
3466620Sgblack@eecs.umich.educonst char *
3476620Sgblack@eecs.umich.eduMC146818::RTCTickEvent::description() const
3486620Sgblack@eecs.umich.edu{
3496620Sgblack@eecs.umich.edu    return "RTC clock tick";
3506620Sgblack@eecs.umich.edu}
351