@@ -46,6 +46,27 @@ static uint64_t get_ns(CPUARCState *env)
4646#endif
4747}
4848
49+ uint64_t arc_get_cycles (CPUARCState * env )
50+ {
51+ uint64_t diff = get_ns (env ) - env -> rtc .base_time_ns ;
52+
53+ /*
54+ * In user mode host's cycles are stored in base_time_ns and get_ns()
55+ * returns host cycles. Thus, return just a difference in this case
56+ * without converting from nanoseconds to cycles.
57+ */
58+ #ifndef CONFIG_USER_ONLY
59+ return NS_TO_CYCLE (diff );
60+ #else
61+ return diff ;
62+ #endif
63+ }
64+
65+ uint64_t arc_get_global_cycles (void )
66+ {
67+ return arc_get_cycles (& ARC_CPU (first_cpu )-> env );
68+ }
69+
4970static uint32_t get_t_count (CPUARCState * env , uint32_t t )
5071{
5172#ifndef CONFIG_USER_ONLY
@@ -141,78 +162,6 @@ static void arc_timer1_cb(void *opaque)
141162}
142163#endif
143164
144- /* RTC counter update. */
145- static void cpu_rtc_count_update (CPUARCState * env )
146- {
147- uint64_t now ;
148- uint64_t llreg ;
149-
150- assert ((env_archcpu (env )-> timer_build & TB_RTC ) && env -> cpu_rtc );
151- now = get_ns (env );
152-
153- if (!(env -> aux_rtc_ctrl & 0x01 )) {
154- return ;
155- }
156-
157- llreg = ((now - env -> last_clk_rtc ) / TIMER_PERIOD (FREQ_HZ ));
158- llreg += env -> aux_rtc_low + ((uint64_t )env -> aux_rtc_high << 32 );
159- env -> aux_rtc_high = llreg >> 32 ;
160- env -> aux_rtc_low = (uint32_t ) llreg ;
161-
162- env -> last_clk_rtc = now ;
163- qemu_log_mask (LOG_UNIMP , "[RTC] RTC count-regs update\n" );
164- }
165-
166- #ifndef CONFIG_USER_ONLY
167- /* Update the next timeout time as difference between Count and Limit */
168- static void cpu_rtc_update (CPUARCState * env )
169- {
170- uint64_t wait = 0 ;
171- uint64_t now , period ;
172- uint64_t next ;
173-
174- assert (env -> cpu_rtc );
175- now = get_ns (env );
176-
177- if (!(env -> aux_rtc_ctrl & 0x01 )) {
178- return ;
179- }
180-
181- period = TIMER_PERIOD (FREQ_HZ );
182- wait = UINT64_MAX - ((((uint64_t ) env -> aux_rtc_high ) << 32 )
183- + env -> aux_rtc_low );
184- wait -= (now - env -> last_clk_rtc ) / period ;
185-
186- /* Limit timeout rate. */
187- if ((wait * period ) < TIMEOUT_LIMIT ) {
188- period = TIMEOUT_LIMIT / wait ;
189- }
190-
191- next = now + (uint64_t ) wait * period ;
192- timer_mod (env -> cpu_rtc , next );
193- qemu_log_mask (LOG_UNIMP , "[RTC] RTC update\n" );
194- }
195- #endif
196-
197- #ifndef CONFIG_USER_ONLY
198- /* RTC call back routine. */
199- static void arc_rtc_cb (void * opaque )
200- {
201- CPUARCState * env = (CPUARCState * ) opaque ;
202-
203- if (!(env_archcpu (env )-> timer_build & TB_RTC )) {
204- return ;
205- }
206-
207- qemu_log_mask (LOG_UNIMP , "[RTC] RTC expired\n" );
208-
209- env -> aux_rtc_high = 0 ;
210- env -> aux_rtc_low = 0 ;
211- env -> last_clk_rtc = get_ns (env );
212- cpu_rtc_update (env );
213- }
214- #endif
215-
216165/* Helper used when resetting the system. */
217166static void cpu_arc_count_reset (CPUARCState * env , uint32_t timer )
218167{
@@ -284,35 +233,88 @@ static void cpu_arc_control_set(CPUARCState *env,
284233 }
285234}
286235
287- /* Get The RTC count value. */
288- static uint32_t arc_rtc_count_get (CPUARCState * env , bool lower )
236+ #if defined( TARGET_ARC64 )
237+ static uint64_t arc_rtc_count_get_low (CPUARCState * env )
289238{
290- cpu_rtc_count_update (env );
291- return lower ? env -> aux_rtc_low : env -> aux_rtc_high ;
239+ uint8_t enabled = FIELD_EX32 (env -> rtc .ctrl , ARC_RTC_CTRL , ENABLE );
240+
241+ if (enabled ) {
242+ return arc_get_cycles (env );
243+ } else {
244+ return env -> rtc .stop_cycles ;
245+ }
292246}
247+ #else
248+ static uint32_t arc_rtc_count_get_low (CPUARCState * env )
249+ {
250+ uint8_t enabled = FIELD_EX32 (env -> rtc .ctrl , ARC_RTC_CTRL , ENABLE );
251+ uint64_t cycles ;
252+
253+ if (enabled ) {
254+ cycles = arc_get_cycles (env );
255+ } else {
256+ cycles = env -> rtc .stop_cycles ;
257+ }
258+
259+ /*
260+ * If RTC is enabled then update (high,low) pair with the latest cycles
261+ * count. Otherwise, don't update it and use the old value.
262+ */
263+ env -> rtc .low = cycles & 0xFFFFFFFF ;
264+ env -> rtc .high = (cycles >> 32 ) & 0xFFFFFFFF ;
265+
266+ return env -> rtc .low ;
267+ }
268+
269+ static uint32_t arc_rtc_count_get_high (CPUARCState * env )
270+ {
271+ return env -> rtc .high ;
272+ }
273+ #endif
293274
294275/* Set the RTC control bits. */
295276static void arc_rtc_ctrl_set (CPUARCState * env , uint32_t val )
296277{
297278#ifndef CONFIG_USER_ONLY
279+ uint8_t enable = FIELD_EX32 (val , ARC_RTC_CTRL , ENABLE );
280+ uint8_t enabled = FIELD_EX32 (env -> rtc .ctrl , ARC_RTC_CTRL , ENABLE );
281+ uint8_t clear = FIELD_EX32 (val , ARC_RTC_CTRL , CLEAR );
282+
298283 assert (GET_STATUS_BIT (env -> stat , Uf ) == 0 );
299284
300- if (val & 0x02 ) {
301- env -> aux_rtc_low = 0 ;
302- env -> aux_rtc_high = 0 ;
303- env -> last_clk_rtc = get_ns (env );
285+ /* Case: RTC is enabled and it's going to be disabled.
286+ * Remember stop time and save the latest cycles count for further using.
287+ */
288+ if (enabled && !enable ) {
289+ env -> rtc .stop_time_ns = get_ns (env );
290+ env -> rtc .stop_cycles = arc_get_cycles (env );
304291 }
305- if (!(val & 0x01 )) {
306- timer_del (env -> cpu_rtc );
292+
293+ if (clear ) {
294+ env -> rtc .base_time_ns = get_ns (env );
295+
296+ /*
297+ * If RTC is stopped then remember stop time - it will allow to reset
298+ * the counter after reactivating the RTC.
299+ */
300+ if (!enabled ) {
301+ env -> rtc .stop_time_ns = env -> rtc .base_time_ns ;
302+ env -> rtc .stop_cycles = 0 ;
303+ }
307304 }
308305
309- /* Restart RTC, update last clock. */
310- if ((env -> aux_rtc_ctrl & 0x01 ) == 0 && (val & 0x01 )) {
311- env -> last_clk_rtc = get_ns (env );
306+ /*
307+ * Case: RTC is disabled and it's going to be enabled.
308+ * Increase base time to fill the gap between stop and now.
309+ */
310+ if (!enabled && enable ) {
311+ env -> rtc .base_time_ns += get_ns (env ) - env -> rtc .stop_time_ns ;
312312 }
313313
314- env -> aux_rtc_ctrl = 0xc0000000 | (val & 0x01 );
315- cpu_rtc_update (env );
314+ /* Always set atomicity bits since. */
315+ env -> rtc .ctrl = FIELD_DP32 (env -> rtc .ctrl , ARC_RTC_CTRL , ENABLE , enable );
316+ env -> rtc .ctrl = FIELD_DP32 (env -> rtc .ctrl , ARC_RTC_CTRL , A0 , 1 );
317+ env -> rtc .ctrl = FIELD_DP32 (env -> rtc .ctrl , ARC_RTC_CTRL , A1 , 1 );
316318#endif
317319}
318320
@@ -324,47 +326,65 @@ cpu_arc_clock_init(ARCCPU *cpu)
324326 CPUARCState * env = & cpu -> env ;
325327
326328#ifndef CONFIG_USER_ONLY
327- if (env_archcpu (env )-> timer_build & TB_T0 ) {
328- env -> cpu_timer [0 ] =
329- timer_new_ns (QEMU_CLOCK_VIRTUAL , & arc_timer0_cb , env );
329+ if (FIELD_EX32 (cpu -> timer_build , ARC_TIMER_BUILD , T0 )) {
330+ env -> cpu_timer [0 ] = timer_new_ns (QEMU_CLOCK_VIRTUAL , & arc_timer0_cb , env );
330331 }
331332
332- if (env_archcpu (env )-> timer_build & TB_T1 ) {
333- env -> cpu_timer [1 ] =
334- timer_new_ns (QEMU_CLOCK_VIRTUAL , & arc_timer1_cb , env );
335- }
336-
337- if (env_archcpu (env )-> timer_build & TB_RTC ) {
338- env -> cpu_rtc =
339- timer_new_ns (QEMU_CLOCK_VIRTUAL , & arc_rtc_cb , env );
333+ if (FIELD_EX32 (cpu -> timer_build , ARC_TIMER_BUILD , T1 )) {
334+ env -> cpu_timer [1 ] = timer_new_ns (QEMU_CLOCK_VIRTUAL , & arc_timer1_cb , env );
340335 }
341336#endif
342337
343338 env -> timer [0 ].last_clk = get_ns (env );
344339 env -> timer [1 ].last_clk = get_ns (env );
345340}
346341
347- void
348- arc_initializeTIMER (ARCCPU * cpu )
342+ /*
343+ * TODO: Implement setting default interrupt priorities for Timer 0 and Timer 1.
344+ */
345+
346+ void arc_initializeTIMER (ARCCPU * cpu )
349347{
350- CPUARCState * env = & cpu -> env ;
348+ uint32_t build = 0 ;
349+ uint8_t version ;
350+
351+ switch (cpu -> family ) {
352+ case ARC_OPCODE_ARC64 :
353+ version = 0x7 ;
354+ break ;
355+ case ARC_OPCODE_ARC32 :
356+ version = 0x6 ;
357+ break ;
358+ default :
359+ version = 0x4 ;
360+ }
361+
362+ build = FIELD_DP32 (build , ARC_TIMER_BUILD , VERSION , version );
363+
364+ if (cpu -> cfg .has_timer_0 ) {
365+ build = FIELD_DP32 (build , ARC_TIMER_BUILD , T0 , 1 );
366+ }
367+
368+ if (cpu -> cfg .has_timer_1 ) {
369+ build = FIELD_DP32 (build , ARC_TIMER_BUILD , T1 , 1 );
370+ }
371+
372+ if (cpu -> cfg .rtc_option ) {
373+ build = FIELD_DP32 (build , ARC_TIMER_BUILD , RTC , 1 );
374+ }
351375
352- /* FIXME! add default timer priorities. */
353- env_archcpu (env )-> timer_build = 0x04 | (cpu -> cfg .has_timer_0 ? TB_T0 : 0 ) |
354- (cpu -> cfg .has_timer_1 ? TB_T1 : 0 ) |
355- (cpu -> cfg .rtc_option ? TB_RTC : 0 );
376+ cpu -> timer_build = build ;
356377}
357378
358- void
359- arc_resetTIMER (ARCCPU * cpu )
379+ void arc_resetTIMER (ARCCPU * cpu )
360380{
361381 CPUARCState * env = & cpu -> env ;
362382
363- if (env_archcpu ( env ) -> timer_build & TB_T0 ) {
383+ if (FIELD_EX32 ( cpu -> timer_build , ARC_TIMER_BUILD , T0 ) ) {
364384 cpu_arc_count_reset (env , 0 );
365385 }
366386
367- if (env_archcpu ( env ) -> timer_build & TB_T1 ) {
387+ if (FIELD_EX32 ( cpu -> timer_build , ARC_TIMER_BUILD , T1 ) ) {
368388 cpu_arc_count_reset (env , 1 );
369389 }
370390}
@@ -405,15 +425,18 @@ aux_timer_get(const struct arc_aux_reg_detail *aux_reg_detail, void *data)
405425 break ;
406426
407427 case AUX_ID_aux_rtc_low :
408- return arc_rtc_count_get (env , true );
428+ return arc_rtc_count_get_low (env );
409429 break ;
410430
431+ #if !defined(TARGET_ARC64 )
432+ /* AUX_RTC_HIGH register is not presented on ARC HS6x processors. */
411433 case AUX_ID_aux_rtc_high :
412- return arc_rtc_count_get (env , false );
434+ return arc_rtc_count_get_high (env );
413435 break ;
436+ #endif
414437
415438 case AUX_ID_aux_rtc_ctrl :
416- return env -> aux_rtc_ctrl ;
439+ return env -> rtc . ctrl ;
417440 break ;
418441
419442 default :
0 commit comments