malta_io.cc

来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· CC 代码 · 共 694 行 · 第 1/2 页

CC
694
字号
/* * Copyright (c) 2004, 2005 * The Regents of The University of Michigan * All Rights Reserved * * This code is part of the M5 simulator. * * Permission is granted to use, copy, create derivative works and * redistribute this software and such derivative works for any * purpose, so long as the copyright notice above, this grant of * permission, and the disclaimer below appear in all copies made; and * so long as the name of The University of Michigan is not used in * any advertising or publicity pertaining to the use or distribution * of this software without specific, written prior authorization. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH * DAMAGES. * * Authors: Ali G. Saidi *          Andrew L. Schultz *          Miguel J. Serrano *//** @file * Malta I/O including PIC, PIT, RTC, DMA */#include <sys/time.h>#include <deque>#include <string>#include <vector>#include "base/trace.hh"#include "dev/pitreg.h"#include "dev/rtcreg.h"#include "dev/mips/malta_cchip.hh"#include "dev/mips/malta.hh"#include "dev/mips/malta_io.hh"#include "dev/mips/maltareg.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;using namespace TheISA;MaltaIO::RTC::RTC(const string &name, Malta* t, Tick i)    : _name(name), event(t, i), addr(0){    memset(clock_data, 0, sizeof(clock_data));    stat_regA = RTCA_32768HZ | RTCA_1024HZ;    stat_regB = RTCB_PRDC_IE |RTCB_BIN | RTCB_24HR;}voidMaltaIO::RTC::set_time(time_t t){    struct tm tm;    gmtime_r(&t, &tm);    sec = tm.tm_sec;    min = tm.tm_min;    hour = tm.tm_hour;    wday = tm.tm_wday + 1;    mday = tm.tm_mday;    mon = tm.tm_mon + 1;    year = tm.tm_year;    DPRINTFN("Real-time clock set to %s", asctime(&tm));}voidMaltaIO::RTC::writeAddr(const uint8_t data){        panic("MaltaIO::RTC::writeAddr has not been implemented for malta");        /*    if (data <= RTC_STAT_REGD)        addr = data;    else        panic("RTC addresses over 0xD are not implemented.\n");  */}voidMaltaIO::RTC::writeData(const uint8_t data){                panic("MaltaIO::RTC::writeData has not been implemented for malta");                /*    if (addr < RTC_STAT_REGA)        clock_data[addr] = data;    else {        switch (addr) {          case RTC_STAT_REGA:            if (data != (RTCA_32768HZ | RTCA_1024HZ))                panic("Unimplemented RTC register A value write!\n");            stat_regA = data;            break;          case RTC_STAT_REGB:            if ((data & ~(RTCB_PRDC_IE | RTCB_SQWE)) != (RTCB_BIN | RTCB_24HR))                panic("Write to RTC reg B bits that are not implemented!\n");            if (data & RTCB_PRDC_IE) {                if (!event.scheduled())                    event.scheduleIntr();            } else {                if (event.scheduled())                    event.deschedule();            }            stat_regB = data;            break;          case RTC_STAT_REGC:          case RTC_STAT_REGD:            panic("RTC status registers C and D are not implemented.\n");            break;        }    }    */}uint8_tMaltaIO::RTC::readData(){                panic("MaltaIO::RTC::readData() has not been implemented for malta");                /*    if (addr < RTC_STAT_REGA)        return clock_data[addr];    else {        switch (addr) {          case RTC_STAT_REGA:            // toggle UIP bit for linux            stat_regA ^= RTCA_UIP;            return stat_regA;            break;          case RTC_STAT_REGB:            return stat_regB;            break;          case RTC_STAT_REGC:          case RTC_STAT_REGD:            return 0x00;            break;          default:            panic("Shouldn't be here");        }    }    */}voidMaltaIO::RTC::serialize(const string &base, ostream &os){    paramOut(os, base + ".addr", addr);    arrayParamOut(os, base + ".clock_data", clock_data, sizeof(clock_data));    paramOut(os, base + ".stat_regA", stat_regA);    paramOut(os, base + ".stat_regB", stat_regB);}voidMaltaIO::RTC::unserialize(const string &base, Checkpoint *cp,                            const string &section){    paramIn(cp, section, base + ".addr", addr);    arrayParamIn(cp, section, base + ".clock_data", clock_data,                 sizeof(clock_data));    paramIn(cp, section, base + ".stat_regA", stat_regA);    paramIn(cp, section, base + ".stat_regB", stat_regB);    // We're not unserializing the event here, but we need to    // rescehedule the event since curTick was moved forward by the    // checkpoint    event.reschedule(curTick + event.interval);}MaltaIO::RTC::RTCEvent::RTCEvent(Malta*t, Tick i)    : Event(&mainEventQueue), malta(t), interval(i){    DPRINTF(MC146818, "RTC Event Initilizing\n");    warn("MaltaIO::RTC::RTCEvent::process() RTC interrupt has been disabled.");    //schedule(curTick + interval);}voidMaltaIO::RTC::RTCEvent::scheduleIntr(){        panic("MaltaIO::RTC::RTCEvent::scheduleIntr() has not been implemented for malta");  //schedule(curTick + interval);}voidMaltaIO::RTC::RTCEvent::process(){    DPRINTF(MC146818, "RTC Timer Interrupt\n");    schedule(curTick + interval);    //Actually interrupt the processor here    malta->cchip->postRTC();}const char *MaltaIO::RTC::RTCEvent::description() const{    return "malta RTC interrupt";}MaltaIO::PITimer::PITimer(const string &name)    : _name(name), counter0(name + ".counter0"), counter1(name + ".counter1"),      counter2(name + ".counter2"){    counter[0] = &counter0;    counter[1] = &counter0;    counter[2] = &counter0;}voidMaltaIO::PITimer::writeControl(const uint8_t data){        panic("MaltoIO::PITimer::writeControl(data) not implemented inside malta_io.cc");        /*    int rw;    int sel;    sel = GET_CTRL_SEL(data);    if (sel == PIT_READ_BACK)       panic("PITimer Read-Back Command is not implemented.\n");    rw = GET_CTRL_RW(data);    if (rw == PIT_RW_LATCH_COMMAND)        counter[sel]->latchCount();    else {        counter[sel]->setRW(rw);        counter[sel]->setMode(GET_CTRL_MODE(data));        counter[sel]->setBCD(GET_CTRL_BCD(data));    }    */}voidMaltaIO::PITimer::serialize(const string &base, ostream &os){    // serialize the counters    counter0.serialize(base + ".counter0", os);    counter1.serialize(base + ".counter1", os);    counter2.serialize(base + ".counter2", os);}voidMaltaIO::PITimer::unserialize(const string &base, Checkpoint *cp,                                const string &section){    // unserialze the counters    counter0.unserialize(base + ".counter0", cp, section);    counter1.unserialize(base + ".counter1", cp, section);    counter2.unserialize(base + ".counter2", cp, section);}MaltaIO::PITimer::Counter::Counter(const string &name)    : _name(name), event(this), count(0), latched_count(0), period(0),      mode(0), output_high(false), latch_on(false), read_byte(LSB),      write_byte(LSB){}voidMaltaIO::PITimer::Counter::latchCount(){                panic("MaltoIO::PITimer::latchCount(...) not implemented inside malta_io.cc");    // behave like a real latch    /*    if(!latch_on) {        latch_on = true;        read_byte = LSB;        latched_count = count;    }    */}uint8_tMaltaIO::PITimer::Counter::read(){                panic("MaltoIO::PITimer::Count::read(...) not implemented inside malta_io.cc");                return 0;                /*    if (latch_on) {        switch (read_byte) {          case LSB:            read_byte = MSB;            return (uint8_t)latched_count;            break;          case MSB:            read_byte = LSB;            latch_on = false;            return latched_count >> 8;            break;          default:            panic("Shouldn't be here");        }    } else {        switch (read_byte) {          case LSB:            read_byte = MSB;            return (uint8_t)count;            break;          case MSB:            read_byte = LSB;            return count >> 8;            break;          default:            panic("Shouldn't be here");        }    }    */}voidMaltaIO::PITimer::Counter::write(const uint8_t data){                panic("MaltoIO::PITimer::Counter::write(...) not implemented inside malta_io.cc");                /*    switch (write_byte) {      case LSB:        count = (count & 0xFF00) | data;        if (event.scheduled())          event.deschedule();        output_high = false;        write_byte = MSB;        break;      case MSB:        count = (count & 0x00FF) | (data << 8);        period = count;        if (period > 0) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?