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:
commit
1c2949a2ff
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue