malta_io.cc revision 5222
15222Sksewell@umich.edu/* 25222Sksewell@umich.edu * Copyright (c) 2004-2005 The Regents of The University of Michigan 35222Sksewell@umich.edu * All rights reserved. 45222Sksewell@umich.edu * 55222Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without 65222Sksewell@umich.edu * modification, are permitted provided that the following conditions are 75222Sksewell@umich.edu * met: redistributions of source code must retain the above copyright 85222Sksewell@umich.edu * notice, this list of conditions and the following disclaimer; 95222Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright 105222Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the 115222Sksewell@umich.edu * documentation and/or other materials provided with the distribution; 125222Sksewell@umich.edu * neither the name of the copyright holders nor the names of its 135222Sksewell@umich.edu * contributors may be used to endorse or promote products derived from 145222Sksewell@umich.edu * this software without specific prior written permission. 155222Sksewell@umich.edu * 165222Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 175222Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 185222Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 195222Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 205222Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 215222Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 225222Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 235222Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245222Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255222Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265222Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275222Sksewell@umich.edu * 285222Sksewell@umich.edu * Authors: Ali Saidi 295222Sksewell@umich.edu * Andrew Schultz 305222Sksewell@umich.edu * Miguel Serrano 315222Sksewell@umich.edu */ 325222Sksewell@umich.edu 335222Sksewell@umich.edu/** @file 345222Sksewell@umich.edu * Malta I/O including PIC, PIT, RTC, DMA 355222Sksewell@umich.edu */ 365222Sksewell@umich.edu 375222Sksewell@umich.edu#include <sys/time.h> 385222Sksewell@umich.edu 395222Sksewell@umich.edu#include <deque> 405222Sksewell@umich.edu#include <string> 415222Sksewell@umich.edu#include <vector> 425222Sksewell@umich.edu 435222Sksewell@umich.edu#include "base/trace.hh" 445222Sksewell@umich.edu#include "dev/pitreg.h" 455222Sksewell@umich.edu#include "dev/rtcreg.h" 465222Sksewell@umich.edu#include "dev/mips/malta_cchip.hh" 475222Sksewell@umich.edu#include "dev/mips/malta.hh" 485222Sksewell@umich.edu#include "dev/mips/malta_io.hh" 495222Sksewell@umich.edu#include "dev/mips/maltareg.h" 505222Sksewell@umich.edu#include "mem/packet.hh" 515222Sksewell@umich.edu#include "mem/packet_access.hh" 525222Sksewell@umich.edu#include "mem/port.hh" 535222Sksewell@umich.edu#include "params/MaltaIO.hh" 545222Sksewell@umich.edu#include "sim/system.hh" 555222Sksewell@umich.edu 565222Sksewell@umich.eduusing namespace std; 575222Sksewell@umich.eduusing namespace TheISA; 585222Sksewell@umich.edu 595222Sksewell@umich.eduMaltaIO::RTC::RTC(const string &name, Malta* t, Tick i) 605222Sksewell@umich.edu : _name(name), event(t, i), addr(0) 615222Sksewell@umich.edu{ 625222Sksewell@umich.edu memset(clock_data, 0, sizeof(clock_data)); 635222Sksewell@umich.edu stat_regA = RTCA_32768HZ | RTCA_1024HZ; 645222Sksewell@umich.edu stat_regB = RTCB_PRDC_IE |RTCB_BIN | RTCB_24HR; 655222Sksewell@umich.edu} 665222Sksewell@umich.edu 675222Sksewell@umich.eduvoid 685222Sksewell@umich.eduMaltaIO::RTC::set_time(time_t t) 695222Sksewell@umich.edu{ 705222Sksewell@umich.edu struct tm tm; 715222Sksewell@umich.edu gmtime_r(&t, &tm); 725222Sksewell@umich.edu 735222Sksewell@umich.edu sec = tm.tm_sec; 745222Sksewell@umich.edu min = tm.tm_min; 755222Sksewell@umich.edu hour = tm.tm_hour; 765222Sksewell@umich.edu wday = tm.tm_wday + 1; 775222Sksewell@umich.edu mday = tm.tm_mday; 785222Sksewell@umich.edu mon = tm.tm_mon + 1; 795222Sksewell@umich.edu year = tm.tm_year; 805222Sksewell@umich.edu 815222Sksewell@umich.edu DPRINTFN("Real-time clock set to %s", asctime(&tm)); 825222Sksewell@umich.edu} 835222Sksewell@umich.edu 845222Sksewell@umich.eduvoid 855222Sksewell@umich.eduMaltaIO::RTC::writeAddr(const uint8_t data) 865222Sksewell@umich.edu{ 875222Sksewell@umich.edu panic("MaltaIO::RTC::writeAddr has not been implemented for malta"); 885222Sksewell@umich.edu /* 895222Sksewell@umich.edu if (data <= RTC_STAT_REGD) 905222Sksewell@umich.edu addr = data; 915222Sksewell@umich.edu else 925222Sksewell@umich.edu panic("RTC addresses over 0xD are not implemented.\n"); 935222Sksewell@umich.edu */ 945222Sksewell@umich.edu} 955222Sksewell@umich.edu 965222Sksewell@umich.eduvoid 975222Sksewell@umich.eduMaltaIO::RTC::writeData(const uint8_t data) 985222Sksewell@umich.edu{ 995222Sksewell@umich.edu panic("MaltaIO::RTC::writeData has not been implemented for malta"); 1005222Sksewell@umich.edu /* 1015222Sksewell@umich.edu if (addr < RTC_STAT_REGA) 1025222Sksewell@umich.edu clock_data[addr] = data; 1035222Sksewell@umich.edu else { 1045222Sksewell@umich.edu switch (addr) { 1055222Sksewell@umich.edu case RTC_STAT_REGA: 1065222Sksewell@umich.edu if (data != (RTCA_32768HZ | RTCA_1024HZ)) 1075222Sksewell@umich.edu panic("Unimplemented RTC register A value write!\n"); 1085222Sksewell@umich.edu stat_regA = data; 1095222Sksewell@umich.edu break; 1105222Sksewell@umich.edu case RTC_STAT_REGB: 1115222Sksewell@umich.edu if ((data & ~(RTCB_PRDC_IE | RTCB_SQWE)) != (RTCB_BIN | RTCB_24HR)) 1125222Sksewell@umich.edu panic("Write to RTC reg B bits that are not implemented!\n"); 1135222Sksewell@umich.edu 1145222Sksewell@umich.edu if (data & RTCB_PRDC_IE) { 1155222Sksewell@umich.edu if (!event.scheduled()) 1165222Sksewell@umich.edu event.scheduleIntr(); 1175222Sksewell@umich.edu } else { 1185222Sksewell@umich.edu if (event.scheduled()) 1195222Sksewell@umich.edu event.deschedule(); 1205222Sksewell@umich.edu } 1215222Sksewell@umich.edu stat_regB = data; 1225222Sksewell@umich.edu break; 1235222Sksewell@umich.edu case RTC_STAT_REGC: 1245222Sksewell@umich.edu case RTC_STAT_REGD: 1255222Sksewell@umich.edu panic("RTC status registers C and D are not implemented.\n"); 1265222Sksewell@umich.edu break; 1275222Sksewell@umich.edu } 1285222Sksewell@umich.edu } 1295222Sksewell@umich.edu */ 1305222Sksewell@umich.edu 1315222Sksewell@umich.edu} 1325222Sksewell@umich.edu 1335222Sksewell@umich.eduuint8_t 1345222Sksewell@umich.eduMaltaIO::RTC::readData() 1355222Sksewell@umich.edu{ 1365222Sksewell@umich.edu panic("MaltaIO::RTC::readData() has not been implemented for malta"); 1375222Sksewell@umich.edu /* 1385222Sksewell@umich.edu if (addr < RTC_STAT_REGA) 1395222Sksewell@umich.edu return clock_data[addr]; 1405222Sksewell@umich.edu else { 1415222Sksewell@umich.edu switch (addr) { 1425222Sksewell@umich.edu case RTC_STAT_REGA: 1435222Sksewell@umich.edu // toggle UIP bit for linux 1445222Sksewell@umich.edu stat_regA ^= RTCA_UIP; 1455222Sksewell@umich.edu return stat_regA; 1465222Sksewell@umich.edu break; 1475222Sksewell@umich.edu case RTC_STAT_REGB: 1485222Sksewell@umich.edu return stat_regB; 1495222Sksewell@umich.edu break; 1505222Sksewell@umich.edu case RTC_STAT_REGC: 1515222Sksewell@umich.edu case RTC_STAT_REGD: 1525222Sksewell@umich.edu return 0x00; 1535222Sksewell@umich.edu break; 1545222Sksewell@umich.edu default: 1555222Sksewell@umich.edu panic("Shouldn't be here"); 1565222Sksewell@umich.edu } 1575222Sksewell@umich.edu } 1585222Sksewell@umich.edu */ 1595222Sksewell@umich.edu} 1605222Sksewell@umich.edu 1615222Sksewell@umich.eduvoid 1625222Sksewell@umich.eduMaltaIO::RTC::serialize(const string &base, ostream &os) 1635222Sksewell@umich.edu{ 1645222Sksewell@umich.edu paramOut(os, base + ".addr", addr); 1655222Sksewell@umich.edu arrayParamOut(os, base + ".clock_data", clock_data, sizeof(clock_data)); 1665222Sksewell@umich.edu paramOut(os, base + ".stat_regA", stat_regA); 1675222Sksewell@umich.edu paramOut(os, base + ".stat_regB", stat_regB); 1685222Sksewell@umich.edu} 1695222Sksewell@umich.edu 1705222Sksewell@umich.eduvoid 1715222Sksewell@umich.eduMaltaIO::RTC::unserialize(const string &base, Checkpoint *cp, 1725222Sksewell@umich.edu const string §ion) 1735222Sksewell@umich.edu{ 1745222Sksewell@umich.edu paramIn(cp, section, base + ".addr", addr); 1755222Sksewell@umich.edu arrayParamIn(cp, section, base + ".clock_data", clock_data, 1765222Sksewell@umich.edu sizeof(clock_data)); 1775222Sksewell@umich.edu paramIn(cp, section, base + ".stat_regA", stat_regA); 1785222Sksewell@umich.edu paramIn(cp, section, base + ".stat_regB", stat_regB); 1795222Sksewell@umich.edu 1805222Sksewell@umich.edu // We're not unserializing the event here, but we need to 1815222Sksewell@umich.edu // rescehedule the event since curTick was moved forward by the 1825222Sksewell@umich.edu // checkpoint 1835222Sksewell@umich.edu event.reschedule(curTick + event.interval); 1845222Sksewell@umich.edu} 1855222Sksewell@umich.edu 1865222Sksewell@umich.eduMaltaIO::RTC::RTCEvent::RTCEvent(Malta*t, Tick i) 1875222Sksewell@umich.edu : Event(&mainEventQueue), malta(t), interval(i) 1885222Sksewell@umich.edu{ 1895222Sksewell@umich.edu DPRINTF(MC146818, "RTC Event Initilizing\n"); 1905222Sksewell@umich.edu warn("MaltaIO::RTC::RTCEvent::process() RTC interrupt has been disabled."); 1915222Sksewell@umich.edu //schedule(curTick + interval); 1925222Sksewell@umich.edu} 1935222Sksewell@umich.edu 1945222Sksewell@umich.eduvoid 1955222Sksewell@umich.eduMaltaIO::RTC::RTCEvent::scheduleIntr() 1965222Sksewell@umich.edu{ 1975222Sksewell@umich.edu panic("MaltaIO::RTC::RTCEvent::scheduleIntr() has not been implemented for malta"); 1985222Sksewell@umich.edu //schedule(curTick + interval); 1995222Sksewell@umich.edu} 2005222Sksewell@umich.edu 2015222Sksewell@umich.eduvoid 2025222Sksewell@umich.eduMaltaIO::RTC::RTCEvent::process() 2035222Sksewell@umich.edu{ 2045222Sksewell@umich.edu DPRINTF(MC146818, "RTC Timer Interrupt\n"); 2055222Sksewell@umich.edu schedule(curTick + interval); 2065222Sksewell@umich.edu //Actually interrupt the processor here 2075222Sksewell@umich.edu malta->cchip->postRTC(); 2085222Sksewell@umich.edu} 2095222Sksewell@umich.edu 2105222Sksewell@umich.educonst char * 2115222Sksewell@umich.eduMaltaIO::RTC::RTCEvent::description() 2125222Sksewell@umich.edu{ 2135222Sksewell@umich.edu return "malta RTC interrupt"; 2145222Sksewell@umich.edu} 2155222Sksewell@umich.edu 2165222Sksewell@umich.eduMaltaIO::PITimer::PITimer(const string &name) 2175222Sksewell@umich.edu : _name(name), counter0(name + ".counter0"), counter1(name + ".counter1"), 2185222Sksewell@umich.edu counter2(name + ".counter2") 2195222Sksewell@umich.edu{ 2205222Sksewell@umich.edu counter[0] = &counter0; 2215222Sksewell@umich.edu counter[1] = &counter0; 2225222Sksewell@umich.edu counter[2] = &counter0; 2235222Sksewell@umich.edu} 2245222Sksewell@umich.edu 2255222Sksewell@umich.eduvoid 2265222Sksewell@umich.eduMaltaIO::PITimer::writeControl(const uint8_t data) 2275222Sksewell@umich.edu{ 2285222Sksewell@umich.edu panic("MaltoIO::PITimer::writeControl(data) not implemented inside malta_io.cc"); 2295222Sksewell@umich.edu /* 2305222Sksewell@umich.edu int rw; 2315222Sksewell@umich.edu int sel; 2325222Sksewell@umich.edu 2335222Sksewell@umich.edu sel = GET_CTRL_SEL(data); 2345222Sksewell@umich.edu 2355222Sksewell@umich.edu if (sel == PIT_READ_BACK) 2365222Sksewell@umich.edu panic("PITimer Read-Back Command is not implemented.\n"); 2375222Sksewell@umich.edu 2385222Sksewell@umich.edu rw = GET_CTRL_RW(data); 2395222Sksewell@umich.edu 2405222Sksewell@umich.edu if (rw == PIT_RW_LATCH_COMMAND) 2415222Sksewell@umich.edu counter[sel]->latchCount(); 2425222Sksewell@umich.edu else { 2435222Sksewell@umich.edu counter[sel]->setRW(rw); 2445222Sksewell@umich.edu counter[sel]->setMode(GET_CTRL_MODE(data)); 2455222Sksewell@umich.edu counter[sel]->setBCD(GET_CTRL_BCD(data)); 2465222Sksewell@umich.edu } 2475222Sksewell@umich.edu */ 2485222Sksewell@umich.edu} 2495222Sksewell@umich.edu 2505222Sksewell@umich.eduvoid 2515222Sksewell@umich.eduMaltaIO::PITimer::serialize(const string &base, ostream &os) 2525222Sksewell@umich.edu{ 2535222Sksewell@umich.edu // serialize the counters 2545222Sksewell@umich.edu counter0.serialize(base + ".counter0", os); 2555222Sksewell@umich.edu counter1.serialize(base + ".counter1", os); 2565222Sksewell@umich.edu counter2.serialize(base + ".counter2", os); 2575222Sksewell@umich.edu} 2585222Sksewell@umich.edu 2595222Sksewell@umich.eduvoid 2605222Sksewell@umich.eduMaltaIO::PITimer::unserialize(const string &base, Checkpoint *cp, 2615222Sksewell@umich.edu const string §ion) 2625222Sksewell@umich.edu{ 2635222Sksewell@umich.edu // unserialze the counters 2645222Sksewell@umich.edu counter0.unserialize(base + ".counter0", cp, section); 2655222Sksewell@umich.edu counter1.unserialize(base + ".counter1", cp, section); 2665222Sksewell@umich.edu counter2.unserialize(base + ".counter2", cp, section); 2675222Sksewell@umich.edu} 2685222Sksewell@umich.edu 2695222Sksewell@umich.eduMaltaIO::PITimer::Counter::Counter(const string &name) 2705222Sksewell@umich.edu : _name(name), event(this), count(0), latched_count(0), period(0), 2715222Sksewell@umich.edu mode(0), output_high(false), latch_on(false), read_byte(LSB), 2725222Sksewell@umich.edu write_byte(LSB) 2735222Sksewell@umich.edu{ 2745222Sksewell@umich.edu 2755222Sksewell@umich.edu} 2765222Sksewell@umich.edu 2775222Sksewell@umich.eduvoid 2785222Sksewell@umich.eduMaltaIO::PITimer::Counter::latchCount() 2795222Sksewell@umich.edu{ 2805222Sksewell@umich.edu panic("MaltoIO::PITimer::latchCount(...) not implemented inside malta_io.cc"); 2815222Sksewell@umich.edu // behave like a real latch 2825222Sksewell@umich.edu /* 2835222Sksewell@umich.edu if(!latch_on) { 2845222Sksewell@umich.edu latch_on = true; 2855222Sksewell@umich.edu read_byte = LSB; 2865222Sksewell@umich.edu latched_count = count; 2875222Sksewell@umich.edu } 2885222Sksewell@umich.edu */ 2895222Sksewell@umich.edu} 2905222Sksewell@umich.edu 2915222Sksewell@umich.eduuint8_t 2925222Sksewell@umich.eduMaltaIO::PITimer::Counter::read() 2935222Sksewell@umich.edu{ 2945222Sksewell@umich.edu panic("MaltoIO::PITimer::Count::read(...) not implemented inside malta_io.cc"); 2955222Sksewell@umich.edu return 0; 2965222Sksewell@umich.edu /* 2975222Sksewell@umich.edu if (latch_on) { 2985222Sksewell@umich.edu switch (read_byte) { 2995222Sksewell@umich.edu case LSB: 3005222Sksewell@umich.edu read_byte = MSB; 3015222Sksewell@umich.edu return (uint8_t)latched_count; 3025222Sksewell@umich.edu break; 3035222Sksewell@umich.edu case MSB: 3045222Sksewell@umich.edu read_byte = LSB; 3055222Sksewell@umich.edu latch_on = false; 3065222Sksewell@umich.edu return latched_count >> 8; 3075222Sksewell@umich.edu break; 3085222Sksewell@umich.edu default: 3095222Sksewell@umich.edu panic("Shouldn't be here"); 3105222Sksewell@umich.edu } 3115222Sksewell@umich.edu } else { 3125222Sksewell@umich.edu switch (read_byte) { 3135222Sksewell@umich.edu case LSB: 3145222Sksewell@umich.edu read_byte = MSB; 3155222Sksewell@umich.edu return (uint8_t)count; 3165222Sksewell@umich.edu break; 3175222Sksewell@umich.edu case MSB: 3185222Sksewell@umich.edu read_byte = LSB; 3195222Sksewell@umich.edu return count >> 8; 3205222Sksewell@umich.edu break; 3215222Sksewell@umich.edu default: 3225222Sksewell@umich.edu panic("Shouldn't be here"); 3235222Sksewell@umich.edu } 3245222Sksewell@umich.edu } 3255222Sksewell@umich.edu */ 3265222Sksewell@umich.edu} 3275222Sksewell@umich.edu 3285222Sksewell@umich.eduvoid 3295222Sksewell@umich.eduMaltaIO::PITimer::Counter::write(const uint8_t data) 3305222Sksewell@umich.edu{ 3315222Sksewell@umich.edu panic("MaltoIO::PITimer::Counter::write(...) not implemented inside malta_io.cc"); 3325222Sksewell@umich.edu /* 3335222Sksewell@umich.edu switch (write_byte) { 3345222Sksewell@umich.edu case LSB: 3355222Sksewell@umich.edu count = (count & 0xFF00) | data; 3365222Sksewell@umich.edu 3375222Sksewell@umich.edu if (event.scheduled()) 3385222Sksewell@umich.edu event.deschedule(); 3395222Sksewell@umich.edu output_high = false; 3405222Sksewell@umich.edu write_byte = MSB; 3415222Sksewell@umich.edu break; 3425222Sksewell@umich.edu 3435222Sksewell@umich.edu case MSB: 3445222Sksewell@umich.edu count = (count & 0x00FF) | (data << 8); 3455222Sksewell@umich.edu period = count; 3465222Sksewell@umich.edu 3475222Sksewell@umich.edu if (period > 0) { 3485222Sksewell@umich.edu DPRINTF(Malta, "Timer set to curTick + %d\n", 3495222Sksewell@umich.edu count * event.interval); 3505222Sksewell@umich.edu event.schedule(curTick + count * event.interval); 3515222Sksewell@umich.edu } 3525222Sksewell@umich.edu write_byte = LSB; 3535222Sksewell@umich.edu break; 3545222Sksewell@umich.edu } 3555222Sksewell@umich.edu */ 3565222Sksewell@umich.edu} 3575222Sksewell@umich.edu 3585222Sksewell@umich.eduvoid 3595222Sksewell@umich.eduMaltaIO::PITimer::Counter::setRW(int rw_val) 3605222Sksewell@umich.edu{ 3615222Sksewell@umich.edu panic("MaltoIO::PITimer::Counter::setRW(...) not implemented inside malta_io.cc"); 3625222Sksewell@umich.edu /* 3635222Sksewell@umich.edu if (rw_val != PIT_RW_16BIT) 3645222Sksewell@umich.edu panic("Only LSB/MSB read/write is implemented.\n"); 3655222Sksewell@umich.edu */ 3665222Sksewell@umich.edu} 3675222Sksewell@umich.edu 3685222Sksewell@umich.eduvoid 3695222Sksewell@umich.eduMaltaIO::PITimer::Counter::setMode(int mode_val) 3705222Sksewell@umich.edu{ 3715222Sksewell@umich.edu panic("MaltoIO::PITimer::Counter::setMode(...) not implemented inside malta_io.cc"); 3725222Sksewell@umich.edu /* 3735222Sksewell@umich.edu if(mode_val != PIT_MODE_INTTC && mode_val != PIT_MODE_RATEGEN && 3745222Sksewell@umich.edu mode_val != PIT_MODE_SQWAVE) 3755222Sksewell@umich.edu panic("PIT mode %#x is not implemented: \n", mode_val); 3765222Sksewell@umich.edu 3775222Sksewell@umich.edu mode = mode_val; 3785222Sksewell@umich.edu */ 3795222Sksewell@umich.edu} 3805222Sksewell@umich.edu 3815222Sksewell@umich.eduvoid 3825222Sksewell@umich.eduMaltaIO::PITimer::Counter::setBCD(int bcd_val) 3835222Sksewell@umich.edu{ 3845222Sksewell@umich.edu panic("MaltoIO::PITimer::Counter::setBCD(...) not implemented inside malta_io.cc"); 3855222Sksewell@umich.edu /* 3865222Sksewell@umich.edu if (bcd_val != PIT_BCD_FALSE) 3875222Sksewell@umich.edu panic("PITimer does not implement BCD counts.\n"); 3885222Sksewell@umich.edu */ 3895222Sksewell@umich.edu} 3905222Sksewell@umich.edu 3915222Sksewell@umich.edubool 3925222Sksewell@umich.eduMaltaIO::PITimer::Counter::outputHigh() 3935222Sksewell@umich.edu{ 3945222Sksewell@umich.edu panic("MaltoIO::PITimer::Counter::outputHigh(...) not implemented inside malta_io.cc"); 3955222Sksewell@umich.edu return false; 3965222Sksewell@umich.edu /* 3975222Sksewell@umich.edu return output_high; 3985222Sksewell@umich.edu */ 3995222Sksewell@umich.edu} 4005222Sksewell@umich.edu 4015222Sksewell@umich.eduvoid 4025222Sksewell@umich.eduMaltaIO::PITimer::Counter::serialize(const string &base, ostream &os) 4035222Sksewell@umich.edu{ 4045222Sksewell@umich.edu paramOut(os, base + ".count", count); 4055222Sksewell@umich.edu paramOut(os, base + ".latched_count", latched_count); 4065222Sksewell@umich.edu paramOut(os, base + ".period", period); 4075222Sksewell@umich.edu paramOut(os, base + ".mode", mode); 4085222Sksewell@umich.edu paramOut(os, base + ".output_high", output_high); 4095222Sksewell@umich.edu paramOut(os, base + ".latch_on", latch_on); 4105222Sksewell@umich.edu paramOut(os, base + ".read_byte", read_byte); 4115222Sksewell@umich.edu paramOut(os, base + ".write_byte", write_byte); 4125222Sksewell@umich.edu 4135222Sksewell@umich.edu Tick event_tick = 0; 4145222Sksewell@umich.edu if (event.scheduled()) 4155222Sksewell@umich.edu event_tick = event.when(); 4165222Sksewell@umich.edu paramOut(os, base + ".event_tick", event_tick); 4175222Sksewell@umich.edu} 4185222Sksewell@umich.edu 4195222Sksewell@umich.eduvoid 4205222Sksewell@umich.eduMaltaIO::PITimer::Counter::unserialize(const string &base, Checkpoint *cp, 4215222Sksewell@umich.edu const string §ion) 4225222Sksewell@umich.edu{ 4235222Sksewell@umich.edu paramIn(cp, section, base + ".count", count); 4245222Sksewell@umich.edu paramIn(cp, section, base + ".latched_count", latched_count); 4255222Sksewell@umich.edu paramIn(cp, section, base + ".period", period); 4265222Sksewell@umich.edu paramIn(cp, section, base + ".mode", mode); 4275222Sksewell@umich.edu paramIn(cp, section, base + ".output_high", output_high); 4285222Sksewell@umich.edu paramIn(cp, section, base + ".latch_on", latch_on); 4295222Sksewell@umich.edu paramIn(cp, section, base + ".read_byte", read_byte); 4305222Sksewell@umich.edu paramIn(cp, section, base + ".write_byte", write_byte); 4315222Sksewell@umich.edu 4325222Sksewell@umich.edu Tick event_tick; 4335222Sksewell@umich.edu paramIn(cp, section, base + ".event_tick", event_tick); 4345222Sksewell@umich.edu if (event_tick) 4355222Sksewell@umich.edu event.schedule(event_tick); 4365222Sksewell@umich.edu} 4375222Sksewell@umich.edu 4385222Sksewell@umich.eduMaltaIO::PITimer::Counter::CounterEvent::CounterEvent(Counter* c_ptr) 4395222Sksewell@umich.edu : Event(&mainEventQueue) 4405222Sksewell@umich.edu{ 4415222Sksewell@umich.edu interval = (Tick)(Clock::Float::s / 1193180.0); 4425222Sksewell@umich.edu counter = c_ptr; 4435222Sksewell@umich.edu} 4445222Sksewell@umich.edu 4455222Sksewell@umich.eduvoid 4465222Sksewell@umich.eduMaltaIO::PITimer::Counter::CounterEvent::process() 4475222Sksewell@umich.edu{ 4485222Sksewell@umich.edu panic("MaltaIO::PITimer::Counter::CounterEvent::process(...) not implemented inside malta_io.cc"); 4495222Sksewell@umich.edu /* 4505222Sksewell@umich.edu DPRINTF(Malta, "Timer Interrupt\n"); 4515222Sksewell@umich.edu switch (counter->mode) { 4525222Sksewell@umich.edu case PIT_MODE_INTTC: 4535222Sksewell@umich.edu counter->output_high = true; 4545222Sksewell@umich.edu case PIT_MODE_RATEGEN: 4555222Sksewell@umich.edu case PIT_MODE_SQWAVE: 4565222Sksewell@umich.edu break; 4575222Sksewell@umich.edu default: 4585222Sksewell@umich.edu panic("Unimplemented PITimer mode.\n"); 4595222Sksewell@umich.edu } 4605222Sksewell@umich.edu */ 4615222Sksewell@umich.edu} 4625222Sksewell@umich.edu 4635222Sksewell@umich.educonst char * 4645222Sksewell@umich.eduMaltaIO::PITimer::Counter::CounterEvent::description() 4655222Sksewell@umich.edu{ 4665222Sksewell@umich.edu return "malta 8254 Interval timer"; 4675222Sksewell@umich.edu} 4685222Sksewell@umich.edu 4695222Sksewell@umich.eduMaltaIO::MaltaIO(Params *p) 4705222Sksewell@umich.edu : BasicPioDevice(p), malta(p->malta), pitimer(p->name + "pitimer"), 4715222Sksewell@umich.edu rtc(p->name + ".rtc", p->malta, p->frequency) 4725222Sksewell@umich.edu{ 4735222Sksewell@umich.edu pioSize = 0x100; 4745222Sksewell@umich.edu 4755222Sksewell@umich.edu // set the back pointer from malta to myself 4765222Sksewell@umich.edu malta->io = this; 4775222Sksewell@umich.edu 4785222Sksewell@umich.edu timerData = 0; 4795222Sksewell@umich.edu picr = 0; 4805222Sksewell@umich.edu picInterrupting = false; 4815222Sksewell@umich.edu} 4825222Sksewell@umich.edu 4835222Sksewell@umich.eduTick 4845222Sksewell@umich.eduMaltaIO::frequency() const 4855222Sksewell@umich.edu{ 4865222Sksewell@umich.edu return Clock::Frequency / params()->frequency; 4875222Sksewell@umich.edu} 4885222Sksewell@umich.edu 4895222Sksewell@umich.eduTick 4905222Sksewell@umich.eduMaltaIO::read(PacketPtr pkt) 4915222Sksewell@umich.edu{ 4925222Sksewell@umich.edu panic("MaltaIO::read(...) not implemented inside malta_io.cc"); 4935222Sksewell@umich.edu return pioDelay; 4945222Sksewell@umich.edu /* 4955222Sksewell@umich.edu assert(pkt->result == Packet::Unknown); 4965222Sksewell@umich.edu assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); 4975222Sksewell@umich.edu 4985222Sksewell@umich.edu Addr daddr = pkt->getAddr() - pioAddr; 4995222Sksewell@umich.edu 5005222Sksewell@umich.edu DPRINTF(Malta, "io read va=%#x size=%d IOPorrt=%#x\n", pkt->getAddr(), 5015222Sksewell@umich.edu pkt->getSize(), daddr); 5025222Sksewell@umich.edu 5035222Sksewell@umich.edu pkt->allocate(); 5045222Sksewell@umich.edu 5055222Sksewell@umich.edu if (pkt->getSize() == sizeof(uint8_t)) { 5065222Sksewell@umich.edu switch(daddr) { 5075222Sksewell@umich.edu // PIC1 mask read 5085222Sksewell@umich.edu case TSDEV_PIC1_MASK: 5095222Sksewell@umich.edu pkt->set(~mask1); 5105222Sksewell@umich.edu break; 5115222Sksewell@umich.edu case TSDEV_PIC2_MASK: 5125222Sksewell@umich.edu pkt->set(~mask2); 5135222Sksewell@umich.edu break; 5145222Sksewell@umich.edu case TSDEV_PIC1_ISR: 5155222Sksewell@umich.edu // !!! If this is modified 64bit case needs to be too 5165222Sksewell@umich.edu // Pal code has to do a 64 bit physical read because there is 5175222Sksewell@umich.edu // no load physical byte instruction 5185222Sksewell@umich.edu pkt->set(picr); 5195222Sksewell@umich.edu break; 5205222Sksewell@umich.edu case TSDEV_PIC2_ISR: 5215222Sksewell@umich.edu // PIC2 not implemnted... just return 0 5225222Sksewell@umich.edu pkt->set(0x00); 5235222Sksewell@umich.edu break; 5245222Sksewell@umich.edu case TSDEV_TMR0_DATA: 5255222Sksewell@umich.edu pkt->set(pitimer.counter0.read()); 5265222Sksewell@umich.edu break; 5275222Sksewell@umich.edu case TSDEV_TMR1_DATA: 5285222Sksewell@umich.edu pkt->set(pitimer.counter1.read()); 5295222Sksewell@umich.edu break; 5305222Sksewell@umich.edu case TSDEV_TMR2_DATA: 5315222Sksewell@umich.edu pkt->set(pitimer.counter2.read()); 5325222Sksewell@umich.edu break; 5335222Sksewell@umich.edu case TSDEV_RTC_DATA: 5345222Sksewell@umich.edu pkt->set(rtc.readData()); 5355222Sksewell@umich.edu break; 5365222Sksewell@umich.edu case TSDEV_CTRL_PORTB: 5375222Sksewell@umich.edu if (pitimer.counter2.outputHigh()) 5385222Sksewell@umich.edu pkt->set(PORTB_SPKR_HIGH); 5395222Sksewell@umich.edu else 5405222Sksewell@umich.edu pkt->set(0x00); 5415222Sksewell@umich.edu break; 5425222Sksewell@umich.edu default: 5435222Sksewell@umich.edu panic("I/O Read - va%#x size %d\n", pkt->getAddr(), pkt->getSize()); 5445222Sksewell@umich.edu } 5455222Sksewell@umich.edu } else if (pkt->getSize() == sizeof(uint64_t)) { 5465222Sksewell@umich.edu if (daddr == TSDEV_PIC1_ISR) 5475222Sksewell@umich.edu pkt->set<uint64_t>(picr); 5485222Sksewell@umich.edu else 5495222Sksewell@umich.edu panic("I/O Read - invalid addr - va %#x size %d\n", 5505222Sksewell@umich.edu pkt->getAddr(), pkt->getSize()); 5515222Sksewell@umich.edu } else { 5525222Sksewell@umich.edu panic("I/O Read - invalid size - va %#x size %d\n", pkt->getAddr(), pkt->getSize()); 5535222Sksewell@umich.edu } 5545222Sksewell@umich.edu pkt->result = Packet::Success; 5555222Sksewell@umich.edu return pioDelay; 5565222Sksewell@umich.edu */ 5575222Sksewell@umich.edu} 5585222Sksewell@umich.edu 5595222Sksewell@umich.eduTick 5605222Sksewell@umich.eduMaltaIO::write(PacketPtr pkt) 5615222Sksewell@umich.edu{ 5625222Sksewell@umich.edu panic("MaltaIO::write(...) not implemented inside malta_io.cc"); 5635222Sksewell@umich.edu return pioDelay; 5645222Sksewell@umich.edu /* 5655222Sksewell@umich.edu assert(pkt->result == Packet::Unknown); 5665222Sksewell@umich.edu assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); 5675222Sksewell@umich.edu Addr daddr = pkt->getAddr() - pioAddr; 5685222Sksewell@umich.edu 5695222Sksewell@umich.edu DPRINTF(Malta, "io write - va=%#x size=%d IOPort=%#x Data=%#x\n", 5705222Sksewell@umich.edu pkt->getAddr(), pkt->getSize(), pkt->getAddr() & 0xfff, (uint32_t)pkt->get<uint8_t>()); 5715222Sksewell@umich.edu 5725222Sksewell@umich.edu assert(pkt->getSize() == sizeof(uint8_t)); 5735222Sksewell@umich.edu warn ("GOT HERE daddr=0x%x\n", daddr); 5745222Sksewell@umich.edu switch(daddr) { 5755222Sksewell@umich.edu case TSDEV_PIC1_MASK: 5765222Sksewell@umich.edu mask1 = ~(pkt->get<uint8_t>()); 5775222Sksewell@umich.edu if ((picr & mask1) && !picInterrupting) { 5785222Sksewell@umich.edu picInterrupting = true; 5795222Sksewell@umich.edu malta->cchip->postDRIR(55); 5805222Sksewell@umich.edu DPRINTF(Malta, "posting pic interrupt to cchip\n"); 5815222Sksewell@umich.edu } 5825222Sksewell@umich.edu if ((!(picr & mask1)) && picInterrupting) { 5835222Sksewell@umich.edu picInterrupting = false; 5845222Sksewell@umich.edu malta->cchip->clearDRIR(55); 5855222Sksewell@umich.edu DPRINTF(Malta, "clearing pic interrupt\n"); 5865222Sksewell@umich.edu } 5875222Sksewell@umich.edu break; 5885222Sksewell@umich.edu case TSDEV_PIC2_MASK: 5895222Sksewell@umich.edu mask2 = pkt->get<uint8_t>(); 5905222Sksewell@umich.edu //PIC2 Not implemented to interrupt 5915222Sksewell@umich.edu break; 5925222Sksewell@umich.edu case TSDEV_PIC1_ACK: 5935222Sksewell@umich.edu // clear the interrupt on the PIC 5945222Sksewell@umich.edu picr &= ~(1 << (pkt->get<uint8_t>() & 0xF)); 5955222Sksewell@umich.edu if (!(picr & mask1)) 5965222Sksewell@umich.edu malta->cchip->clearDRIR(55); 5975222Sksewell@umich.edu break; 5985222Sksewell@umich.edu case TSDEV_DMA1_MODE: 5995222Sksewell@umich.edu mode1 = pkt->get<uint8_t>(); 6005222Sksewell@umich.edu break; 6015222Sksewell@umich.edu case TSDEV_DMA2_MODE: 6025222Sksewell@umich.edu mode2 = pkt->get<uint8_t>(); 6035222Sksewell@umich.edu break; 6045222Sksewell@umich.edu case TSDEV_TMR0_DATA: 6055222Sksewell@umich.edu pitimer.counter0.write(pkt->get<uint8_t>()); 6065222Sksewell@umich.edu break; 6075222Sksewell@umich.edu case TSDEV_TMR1_DATA: 6085222Sksewell@umich.edu pitimer.counter1.write(pkt->get<uint8_t>()); 6095222Sksewell@umich.edu break; 6105222Sksewell@umich.edu case TSDEV_TMR2_DATA: 6115222Sksewell@umich.edu pitimer.counter2.write(pkt->get<uint8_t>()); 6125222Sksewell@umich.edu break; 6135222Sksewell@umich.edu case TSDEV_TMR_CTRL: 6145222Sksewell@umich.edu pitimer.writeControl(pkt->get<uint8_t>()); 6155222Sksewell@umich.edu break; 6165222Sksewell@umich.edu case TSDEV_RTC_ADDR: 6175222Sksewell@umich.edu rtc.writeAddr(pkt->get<uint8_t>()); 6185222Sksewell@umich.edu break; 6195222Sksewell@umich.edu case TSDEV_RTC_DATA: 6205222Sksewell@umich.edu rtc.writeData(pkt->get<uint8_t>()); 6215222Sksewell@umich.edu break; 6225222Sksewell@umich.edu case TSDEV_KBD: 6235222Sksewell@umich.edu case TSDEV_DMA1_CMND: 6245222Sksewell@umich.edu case TSDEV_DMA2_CMND: 6255222Sksewell@umich.edu case TSDEV_DMA1_MMASK: 6265222Sksewell@umich.edu case TSDEV_DMA2_MMASK: 6275222Sksewell@umich.edu case TSDEV_PIC2_ACK: 6285222Sksewell@umich.edu case TSDEV_DMA1_RESET: 6295222Sksewell@umich.edu case TSDEV_DMA2_RESET: 6305222Sksewell@umich.edu case TSDEV_DMA1_MASK: 6315222Sksewell@umich.edu case TSDEV_DMA2_MASK: 6325222Sksewell@umich.edu case TSDEV_CTRL_PORTB: 6335222Sksewell@umich.edu break; 6345222Sksewell@umich.edu default: 6355222Sksewell@umich.edu panic("I/O Write - va%#x size %d data %#x\n", pkt->getAddr(), pkt->getSize(), pkt->get<uint8_t>()); 6365222Sksewell@umich.edu } 6375222Sksewell@umich.edu 6385222Sksewell@umich.edu pkt->result = Packet::Success; 6395222Sksewell@umich.edu return pioDelay; 6405222Sksewell@umich.edu */ 6415222Sksewell@umich.edu} 6425222Sksewell@umich.edu 6435222Sksewell@umich.eduvoid 6445222Sksewell@umich.eduMaltaIO::postIntr(uint8_t interrupt) 6455222Sksewell@umich.edu{ 6465222Sksewell@umich.edu malta->cchip->postIntr(interrupt); 6475222Sksewell@umich.edu DPRINTF(Malta, "posting pic interrupt to cchip\n"); 6485222Sksewell@umich.edu} 6495222Sksewell@umich.edu 6505222Sksewell@umich.eduvoid 6515222Sksewell@umich.eduMaltaIO::clearIntr(uint8_t interrupt) 6525222Sksewell@umich.edu{ 6535222Sksewell@umich.edu malta->cchip->clearIntr(interrupt); 6545222Sksewell@umich.edu DPRINTF(Malta, "posting pic interrupt to cchip\n"); 6555222Sksewell@umich.edu} 6565222Sksewell@umich.edu 6575222Sksewell@umich.eduvoid 6585222Sksewell@umich.eduMaltaIO::serialize(ostream &os) 6595222Sksewell@umich.edu{ 6605222Sksewell@umich.edu SERIALIZE_SCALAR(timerData); 6615222Sksewell@umich.edu SERIALIZE_SCALAR(mask1); 6625222Sksewell@umich.edu SERIALIZE_SCALAR(mask2); 6635222Sksewell@umich.edu SERIALIZE_SCALAR(mode1); 6645222Sksewell@umich.edu SERIALIZE_SCALAR(mode2); 6655222Sksewell@umich.edu SERIALIZE_SCALAR(picr); 6665222Sksewell@umich.edu SERIALIZE_SCALAR(picInterrupting); 6675222Sksewell@umich.edu 6685222Sksewell@umich.edu // Serialize the timers 6695222Sksewell@umich.edu pitimer.serialize("pitimer", os); 6705222Sksewell@umich.edu rtc.serialize("rtc", os); 6715222Sksewell@umich.edu} 6725222Sksewell@umich.edu 6735222Sksewell@umich.eduvoid 6745222Sksewell@umich.eduMaltaIO::unserialize(Checkpoint *cp, const string §ion) 6755222Sksewell@umich.edu{ 6765222Sksewell@umich.edu UNSERIALIZE_SCALAR(timerData); 6775222Sksewell@umich.edu UNSERIALIZE_SCALAR(mask1); 6785222Sksewell@umich.edu UNSERIALIZE_SCALAR(mask2); 6795222Sksewell@umich.edu UNSERIALIZE_SCALAR(mode1); 6805222Sksewell@umich.edu UNSERIALIZE_SCALAR(mode2); 6815222Sksewell@umich.edu UNSERIALIZE_SCALAR(picr); 6825222Sksewell@umich.edu UNSERIALIZE_SCALAR(picInterrupting); 6835222Sksewell@umich.edu 6845222Sksewell@umich.edu // Unserialize the timers 6855222Sksewell@umich.edu pitimer.unserialize("pitimer", cp, section); 6865222Sksewell@umich.edu rtc.unserialize("rtc", cp, section); 6875222Sksewell@umich.edu} 6885222Sksewell@umich.edu 6895222Sksewell@umich.eduMaltaIO * 6905222Sksewell@umich.eduMaltaIOParams::create() 6915222Sksewell@umich.edu{ 6925222Sksewell@umich.edu return new MaltaIO(this); 6935222Sksewell@umich.edu} 694