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? //Should this be AlphaISA?
using namespace TheISA; using namespace TheISA;
TsunamiIO::RTC::RTC(const string &n, Tsunami* tsunami, time_t t, Tick i) TsunamiIO::RTC::RTC(const string &n, Tsunami* tsunami, const vector<int> &t,
: _name(n), event(tsunami, i), addr(0) bool bcd, Tick i)
: _name(n), event(tsunami, i), addr(0), year_is_bcd(bcd)
{ {
memset(clock_data, 0, sizeof(clock_data)); memset(clock_data, 0, sizeof(clock_data));
stat_regA = RTCA_32768HZ | RTCA_1024HZ; stat_regA = RTCA_32768HZ | RTCA_1024HZ;
stat_regB = RTCB_PRDC_IE |RTCB_BIN | RTCB_24HR; 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; struct tm tm;
gmtime_r(&t, &tm);
sec = tm.tm_sec; memset(&tm, 0, sizeof(tm));
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)); 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 void
@ -424,7 +476,8 @@ TsunamiIO::PITimer::Counter::CounterEvent::description()
TsunamiIO::TsunamiIO(Params *p) TsunamiIO::TsunamiIO(Params *p)
: BasicPioDevice(p), tsunami(p->tsunami), pitimer(p->name + "pitimer"), : 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; pioSize = 0x100;
@ -649,7 +702,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO)
Param<Tick> frequency; Param<Tick> frequency;
SimObjectParam<Platform *> platform; SimObjectParam<Platform *> platform;
SimObjectParam<System *> system; SimObjectParam<System *> system;
Param<time_t> time; VectorParam<int> time;
Param<bool> year_is_bcd;
SimObjectParam<Tsunami *> tsunami; SimObjectParam<Tsunami *> tsunami;
END_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO) END_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO)
@ -662,6 +716,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiIO)
INIT_PARAM(platform, "platform"), INIT_PARAM(platform, "platform"),
INIT_PARAM(system, "system object"), INIT_PARAM(system, "system object"),
INIT_PARAM(time, "System time to use (0 for actual time"), INIT_PARAM(time, "System time to use (0 for actual time"),
INIT_PARAM(year_is_bcd, ""),
INIT_PARAM(tsunami, "Tsunami") INIT_PARAM(tsunami, "Tsunami")
END_INIT_SIM_OBJECT_PARAMS(TsunamiIO) END_INIT_SIM_OBJECT_PARAMS(TsunamiIO)
@ -676,6 +731,7 @@ CREATE_SIM_OBJECT(TsunamiIO)
p->platform = platform; p->platform = platform;
p->system = system; p->system = system;
p->init_time = time; p->init_time = time;
p->year_is_bcd = year_is_bcd;
p->tsunami = tsunami; p->tsunami = tsunami;
return new TsunamiIO(p); return new TsunamiIO(p);
} }

View file

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

View file

@ -13,8 +13,10 @@ class TsunamiCChip(BasicPioDevice):
class TsunamiIO(BasicPioDevice): class TsunamiIO(BasicPioDevice):
type = 'TsunamiIO' type = 'TsunamiIO'
time = Param.Time('01/01/2009', time = Param.Time('01/01/2006',
"System time to use ('Now' for actual time)") "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") tsunami = Param.Tsunami(Parent.any, "Tsunami")
frequency = Param.Frequency('1024Hz', "frequency of interrupts") frequency = Param.Frequency('1024Hz', "frequency of interrupts")

View file

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