Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / devices / tod_4v / tod.cc
CommitLineData
920dae64
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: tod.cc
4// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
5// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
6//
7// The above named program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public
9// License version 2 as published by the Free Software Foundation.
10//
11// The above named program is distributed in the hope that it will be
12// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14// General Public License for more details.
15//
16// You should have received a copy of the GNU General Public
17// License along with this work; if not, write to the Free Software
18// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19//
20// ========== Copyright Header End ============================================
21#include "tod.h"
22
23
24static const char *tod_4v_help = "\
25SAM N2 tod module (for Legion's virtual tod device)\n\
26Sysconf format is :\n\
27sysconf tod_4v <instance_name> base_pa=<start_addr> size=<map size> [tod=<mmddHHMMSSyyyy>]\n\
28\'base_pa\' is the start address of memory mapped address, of the device CSRs\n\
29\'size\' is the size of the CSR space\n\
30\'tod\' is the time of day initial value. If ignored, current host system time is read\n\
31For UI help type <instance name>\n\
32For module specific info type \"modinfo <instance name>\"";
33
34
35Module *Module::create(const char *_modname, const char *_instance_name){
36 return new tod4v(_modname, _instance_name);
37}
38const char * tod4v::get_help(){
39 return Module::get_help_string();
40}
41
42const char *
43Module::get_help_string(){
44 return tod_4v_help;
45}
46
47tod4v::tod4v(const char * modname,const char * instance_name)
48 :Module(modname,instance_name){
49 start_pa = -1;
50 end_pa = 0;
51 size = 0;
52 set_fake_tod = false;
53 todstr = 0;
54 sim_time = 0;
55 event_fire_time = 0;
56 mmi_register_instance_cmd(getInstance(),tod_4v_help,tod_4v_ui_cmd);
57}
58
59bool tod4v::parse_arg(const char * arg){
60 if(argval("base",arg,&start_pa)){
61 debug_more("%s: base_pa %llx\n",getName(), start_pa);
62 return true;
63 }else if(argval("size",arg,&size)){
64 debug_more("%s: size %llx, end_pa %llx\n",getName(), size, start_pa + size - 1);
65 return true;
66 }else if(argval("tod",arg,&todstr)){
67 /* tod format is mmddHHMMSSyyyy , fakeSC.cc */
68 char buf[10];
69 char null[1];
70 null[0] = '\0';
71 if(strlen(todstr) != 14){
72 printf("tod format(mmddHHMMSSyyyy) incorrectly specified\n");
73 return false;
74 }
75 set_fake_tod = true;
76 time_str.tm_mon = atoi(strcpy(strncpy(buf,todstr,2) + 2,null) - 2) - 1;
77 time_str.tm_mday = atoi(strcpy(strncpy(buf,todstr+2,2) + 2,null) - 2);
78 time_str.tm_hour = atoi(strcpy(strncpy(buf,todstr+4,2) + 2,null)- 2);
79 time_str.tm_min = atoi(strcpy(strncpy(buf,todstr+6,2) + 2,null) - 2);
80 time_str.tm_sec = atoi(strcpy(strncpy(buf,todstr+8,2) + 2, null) - 2);
81 time_str.tm_year = atoi(strcpy(strncpy(buf,todstr+10,4) + 4,null) - 4) - 1900;
82 time_str.tm_isdst = -1;
83 }else
84 return false;
85}
86
87
88bool tod4v::check_args(){
89
90 if(start_pa == -1){
91 debug_err("%s:must specify start address\n",getName());
92 return false;
93 }else if(size == 0){
94 debug_err("%s:must specify size of address mapping\n",getName());
95 return false;
96 }else
97 return true;
98}
99
100void tod4v::init_done(){
101
102 if(mmi_map_physio(start_pa, size, (void *) this, tod4v_physio_access) != 0) {
103 debug_err("%s fatal error: unaable to map IO space\n");
104 exit(1);
105 }
106
107 end_pa = start_pa + size - 1;
108
109 if(set_fake_tod)
110 tod = mktime(&time_str);
111 else
112 tod = time(0);
113
114
115 // register a callback to fire every 1 sec, to increment the time
116
117 if(!restore_v5_dump()){
118 mmi_register_event(1000000,tod_1sec_callback,(void*)this,0);
119 event_fire_time = 1000000;
120 }
121}
122
123
124int tod4v::tod4v_physio_access(uint32_t cpuid, void* obj, uint64_t paddr,
125 mmi_bool_t wr, uint32_t size, uint64_t* buf, uint8_t bytemask){
126 tod4v* s = (tod4v*) obj;
127
128 if(wr)
129 s->tod4v_st(paddr,buf,size);
130 else
131 s->tod4v_ld(paddr,buf,size);
132 return 0;
133}
134
135int tod_4v_ui_cmd(void * obj, int argc, char * argv[]){
136 tod4v * i = (tod4v *)obj;
137 i->handle_ui(argc, argv);
138 return 0;
139}
140
141void tod4v::handle_ui(int argc, char * argv[]){
142 // dump restore are unpublished debug UI's
143 if(argc == 1){
144 ui_cmd_usage();
145 return;
146 }else if(!strcmp(argv[1],"dump")){
147 FILE * fp = stderr;
148 if(argv[2]){
149 fp = fopen(argv[2],"w");
150 if(!fp){
151 printf("%s dump: error opening file <%s>\n",getName(),argv[2]);
152 fp = stderr;
153 }
154 }
155 dump(fp);
156 if(fp != stderr)
157 fclose(fp);
158 }else if(!strcmp(argv[1],"restore")){
159 FILE * fp;
160 if(argv[2]){
161 fp = fopen(argv[2],"r");
162 if(fp){
163 restore(fp);
164 fclose(fp);
165 }else
166 printf("%s restore: error opening file <%s>\n",getName(),argv[2]);
167 }else
168 printf("%s restore: no restore filename specified\n",getName());
169 }else if(!strcmp(argv[1],"debug")){
170 if(argv[2]){
171 debug_level = atoi(argv[2]);
172 printf("%s: set debug level to %d\n",getName(),debug_level);
173 }else
174 printf("%s: current debug level %d\n",getName(),debug_level);
175 }else
176 debug_err("%s: unsupported UI command <%s>\n",getName(),argv[1]);
177 return;
178}
179
180void tod4v::tod4v_ld (uint64_t paddr, uint64_t *buf, int size){
181 uint64_t offset = paddr - start_pa;
182 assert(offset == 0);
183 assert(size == 8);
184 *buf = tod;
185 debug_more("%s: ld pa 0x%llx size %d value %llx \n", getName(), paddr, size, *buf );
186 return;
187}
188
189
190void tod4v::tod4v_st(uint64_t pa, uint64_t *buf, int size){
191 debug_err("%s: does not support store\n",getName());
192 debug_err("%s: st pa 0x%llx size %d value %llx\n",getName(),pa,size,*buf);
193 return;
194}
195
196
197void tod4v::timer_callback(){
198 tod += 1;
199 sim_time++;
200 debug_more("%s: sim time %i sec : current time of day %s", getName(),sim_time,ctime(&tod));
201 event_fire_time = mmi_get_time()+1000000;
202 mmi_register_event(event_fire_time,tod_1sec_callback,(void*)this,0);
203}
204
205void tod_1sec_callback(void * obj, void * ){
206 tod4v * t = (tod4v*) obj;
207 t->timer_callback();
208}
209