Commit | Line | Data |
---|---|---|
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 | ||
24 | static const char *tod_4v_help = "\ | |
25 | SAM N2 tod module (for Legion's virtual tod device)\n\ | |
26 | Sysconf format is :\n\ | |
27 | sysconf 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\ | |
31 | For UI help type <instance name>\n\ | |
32 | For module specific info type \"modinfo <instance name>\""; | |
33 | ||
34 | ||
35 | Module *Module::create(const char *_modname, const char *_instance_name){ | |
36 | return new tod4v(_modname, _instance_name); | |
37 | } | |
38 | const char * tod4v::get_help(){ | |
39 | return Module::get_help_string(); | |
40 | } | |
41 | ||
42 | const char * | |
43 | Module::get_help_string(){ | |
44 | return tod_4v_help; | |
45 | } | |
46 | ||
47 | tod4v::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 | ||
59 | bool 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 | ||
88 | bool 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 | ||
100 | void 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 | ||
124 | int 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 | ||
135 | int 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 | ||
141 | void 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 | ||
180 | void 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 | ||
190 | void 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 | ||
197 | void 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 | ||
205 | void tod_1sec_callback(void * obj, void * ){ | |
206 | tod4v * t = (tod4v*) obj; | |
207 | t->timer_callback(); | |
208 | } | |
209 |