Merge zizzer.eecs.umich.edu:/bk/newmem

into  zeep.pool:/y/binkertn/research/m5/rtc

--HG--
extra : convert_revision : 65ddda89f38c5fa874722c20e5d82ed1bb4e12d9
This commit is contained in:
Nathan Binkert 2007-01-25 15:00:04 -05:00
commit 1c2949a2ff
4 changed files with 121 additions and 48 deletions

View file

@ -57,25 +57,77 @@ using namespace std;
//Should this be AlphaISA?
using namespace TheISA;
TsunamiIO::RTC::RTC(const string &n, Tsunami* tsunami, time_t t, Tick i)
: _name(n), event(tsunami, i), addr(0)
TsunamiIO::RTC::RTC(const string &n, Tsunami* tsunami, const vector<int> &t,
bool bcd, Tick i)
: _name(n), event(tsunami, i), addr(0), year_is_bcd(bcd)
{
memset(clock_data, 0, sizeof(clock_data));
stat_regA = RTCA_32768HZ | RTCA_1024HZ;
stat_regB = RTCB_PRDC_IE |RTCB_BIN | RTCB_24HR;
if (year_is_bcd) {
// The RTC uses BCD for the last two digits in the year.
// They python year is a full year.
int _year = t[0] % 100;
int tens = _year / 10;
int ones = _year % 10;
year = (tens << 4) + ones;
} else {
// Even though the datasheet says that the year field should be
// interpreted as BCD, we just enter the number of years since
// 1900 since linux seems to be happy with that (and I believe
// that Tru64 was as well)
year = t[0] - 1900;
}
mon = t[1];
mday = t[2];
hour = t[3];
min = t[4];
sec = t[5];
// wday is defined to be in the range from 1 - 7 with 1 being Sunday.
// the value coming from python is in the range from 0 - 6 with 0 being
// Monday. Fix that here.
wday = t[6] + 2;
if (wday > 7)
wday -= 7;
DPRINTFN("Real-time clock set to %s", getDateString());
}
std::string
TsunamiIO::RTC::getDateString()
{
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;
memset(&tm, 0, sizeof(tm));
DPRINTFN("Real-time clock set to %s", asctime(&tm));
if (year_is_bcd) {
// undo the BCD and conver to years since 1900 guessing that
// anything before 1970 is actually after 2000
int _year = (year >> 4) * 10 + (year & 0xf);
if (_year < 70)
_year += 100;
tm.tm_year = _year;
} else {
// number of years since 1900
tm.tm_year = year;
}
// unix is 0-11 for month
tm.tm_mon = mon - 1;
tm.tm_mday = mday;
tm.tm_hour = hour;
tm.tm_min = min;
tm.tm_sec = sec;
// to add more annoyance unix is 0 - 6 with 0 as sunday
tm.tm_wday = wday - 1;
return asctime(&tm);
}
void
@ -424,7 +476,8 @@ TsunamiIO::PITimer::Counter::CounterEvent::description()
TsunamiIO::TsunamiIO(Params *p)
: BasicPioDevice(p), tsunami(p->tsunami), pitimer(p->name + "pitimer"),
rtc(p->name + ".rtc", p->tsunami, p->init_time, p->frequency)
rtc(p->name + ".rtc", p->tsunami, p->init_time, p->year_is_bcd,
p->frequency)
{
pioSize = 0x100;
@ -649,7 +702,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO)
Param<Tick> frequency;
SimObjectParam<Platform *> platform;
SimObjectParam<System *> system;
Param<time_t> time;
VectorParam<int> time;
Param<bool> year_is_bcd;
SimObjectParam<Tsunami *> tsunami;
END_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO)
@ -662,6 +716,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiIO)
INIT_PARAM(platform, "platform"),
INIT_PARAM(system, "system object"),
INIT_PARAM(time, "System time to use (0 for actual time"),
INIT_PARAM(year_is_bcd, ""),
INIT_PARAM(tsunami, "Tsunami")
END_INIT_SIM_OBJECT_PARAMS(TsunamiIO)
@ -676,6 +731,7 @@ CREATE_SIM_OBJECT(TsunamiIO)
p->platform = platform;
p->system = system;
p->init_time = time;
p->year_is_bcd = year_is_bcd;
p->tsunami = tsunami;
return new TsunamiIO(p);
}

View file

@ -85,6 +85,9 @@ class TsunamiIO : public BasicPioDevice
/** Current RTC register address/index */
int addr;
/** should the year be interpreted as BCD? */
bool year_is_bcd;
/** Data for real-time clock function */
union {
uint8_t clock_data[10];
@ -110,7 +113,8 @@ class TsunamiIO : public BasicPioDevice
uint8_t stat_regB;
public:
RTC(const std::string &name, Tsunami* tsunami, time_t t, Tick i);
RTC(const std::string &name, Tsunami* tsunami,
const std::vector<int> &t, bool bcd, Tick i);
/** RTC address port: write address of RTC RAM data to access */
void writeAddr(const uint8_t data);
@ -121,6 +125,9 @@ class TsunamiIO : public BasicPioDevice
/** RTC read data */
uint8_t readData();
/** RTC get the date */
std::string getDateString();
/**
* Serialize this object to the given output stream.
* @param base The base name of the counter object.
@ -313,8 +320,10 @@ class TsunamiIO : public BasicPioDevice
{
Tick frequency;
Tsunami *tsunami;
time_t init_time;
std::vector<int> init_time;
bool year_is_bcd;
};
protected:
const Params *params() const { return (const Params*)_params; }

View file

@ -13,8 +13,10 @@ class TsunamiCChip(BasicPioDevice):
class TsunamiIO(BasicPioDevice):
type = 'TsunamiIO'
time = Param.Time('01/01/2009',
time = Param.Time('01/01/2006',
"System time to use ('Now' for actual time)")
year_is_bcd = Param.Bool(False,
"The RTC should interpret the year as a BCD value")
tsunami = Param.Tsunami(Parent.any, "Tsunami")
frequency = Param.Frequency('1024Hz', "frequency of interrupts")

View file

@ -518,49 +518,55 @@ class EthernetAddr(ParamValue):
else:
return self.value
def parse_time(value):
strings = [ "%a %b %d %H:%M:%S %Z %Y",
"%a %b %d %H:%M:%S %Z %Y",
"%Y/%m/%d %H:%M:%S",
"%Y/%m/%d %H:%M",
"%Y/%m/%d",
"%m/%d/%Y %H:%M:%S",
"%m/%d/%Y %H:%M",
"%m/%d/%Y",
"%m/%d/%y %H:%M:%S",
"%m/%d/%y %H:%M",
"%m/%d/%y"]
time_formats = [ "%a %b %d %H:%M:%S %Z %Y",
"%a %b %d %H:%M:%S %Z %Y",
"%Y/%m/%d %H:%M:%S",
"%Y/%m/%d %H:%M",
"%Y/%m/%d",
"%m/%d/%Y %H:%M:%S",
"%m/%d/%Y %H:%M",
"%m/%d/%Y",
"%m/%d/%y %H:%M:%S",
"%m/%d/%y %H:%M",
"%m/%d/%y"]
for string in strings:
try:
return time.strptime(value, string)
except ValueError:
pass
def parse_time(value):
from time import gmtime, strptime, struct_time, time
from datetime import datetime, date
if isinstance(value, struct_time):
return value
if isinstance(value, (int, long)):
return gmtime(value)
if isinstance(value, (datetime, date)):
return value.timetuple()
if isinstance(value, str):
if value in ('Now', 'Today'):
return time.gmtime(time.time())
for format in time_formats:
try:
return strptime(value, format)
except ValueError:
pass
raise ValueError, "Could not parse '%s' as a time" % value
class Time(ParamValue):
cxx_type = 'time_t'
def __init__(self, value):
if isinstance(value, time.struct_time):
self.value = time.mktime(value)
elif isinstance(value, int):
self.value = value
elif isinstance(value, str):
if value in ('Now', 'Today'):
self.value = time.time()
else:
self.value = time.mktime(parse_time(value))
elif isinstance(value, (datetime.datetime, datetime.date)):
self.value = time.mktime(value.timetuple())
else:
raise ValueError, "Could not parse '%s' as a time" % value
self.value = parse_time(value)
def __str__(self):
return str(int(self.value))
tm = self.value
return ' '.join([ str(tm[i]) for i in xrange(8)])
def ini_str(self):
return str(int(self.value))
return str(self)
# Enumerated types are a little more complex. The user specifies the
# type as Enum(foo) where foo is either a list or dictionary of