@@ -47,21 +47,23 @@ REG32(ALERT_TEST, 0x00u)
47
47
REG32 (WKUP_CTRL , 0x04u )
48
48
FIELD (WKUP_CTRL , ENABLE , 0u , 1u )
49
49
FIELD (WKUP_CTRL , PRESCALER , 1u , 12u )
50
- REG32 (WKUP_THOLD , 0x08 )
51
- REG32 (WKUP_COUNT , 0x0cu )
52
- REG32 (WDOG_REGWEN , 0x10u )
50
+ REG32 (WKUP_THOLD_HI , 0x08u )
51
+ REG32 (WKUP_THOLD_LO , 0x0cu )
52
+ REG32 (WKUP_COUNT_HI , 0x10u )
53
+ REG32 (WKUP_COUNT_LO , 0x14u )
54
+ REG32 (WDOG_REGWEN , 0x18u )
53
55
FIELD (WDOG_REGWEN , REGWEN , 0u , 1u )
54
- REG32 (WDOG_CTRL , 0x14u )
56
+ REG32 (WDOG_CTRL , 0x1cu )
55
57
FIELD (WDOG_CTRL , ENABLE , 0u , 1u )
56
- FIELD (WDOG_CTRL , PAUSE_IN_SLEEP , 0u , 1u )
57
- REG32 (WDOG_BARK_THOLD , 0x18u )
58
- REG32 (WDOG_BITE_THOLD , 0x1cu )
59
- REG32 (WDOG_COUNT , 0x20u )
60
- REG32 (INTR_STATE , 0x24u )
58
+ FIELD (WDOG_CTRL , PAUSE_IN_SLEEP , 1u , 1u )
59
+ REG32 (WDOG_BARK_THOLD , 0x20u )
60
+ REG32 (WDOG_BITE_THOLD , 0x24u )
61
+ REG32 (WDOG_COUNT , 0x28u )
62
+ REG32 (INTR_STATE , 0x2cu )
61
63
SHARED_FIELD (INTR_WKUP_TIMER_EXPIRED , 0u , 1u )
62
64
SHARED_FIELD (INTR_WDOG_TIMER_BARK , 1u , 1u )
63
- REG32 (INTR_TEST , 0x28u )
64
- REG32 (WKUP_CAUSE , 0x2cu )
65
+ REG32 (INTR_TEST , 0x30u )
66
+ REG32 (WKUP_CAUSE , 0x34u )
65
67
FIELD (WKUP_CAUSE , CAUSE , 0u , 1u )
66
68
/* clang-format on */
67
69
@@ -80,8 +82,10 @@ static const char REG_NAMES[REGS_COUNT][20u] = {
80
82
/* clang-format off */
81
83
REG_NAME_ENTRY (ALERT_TEST ),
82
84
REG_NAME_ENTRY (WKUP_CTRL ),
83
- REG_NAME_ENTRY (WKUP_THOLD ),
84
- REG_NAME_ENTRY (WKUP_COUNT ),
85
+ REG_NAME_ENTRY (WKUP_THOLD_HI ),
86
+ REG_NAME_ENTRY (WKUP_THOLD_LO ),
87
+ REG_NAME_ENTRY (WKUP_COUNT_HI ),
88
+ REG_NAME_ENTRY (WKUP_COUNT_LO ),
85
89
REG_NAME_ENTRY (WDOG_REGWEN ),
86
90
REG_NAME_ENTRY (WDOG_CTRL ),
87
91
REG_NAME_ENTRY (WDOG_BARK_THOLD ),
@@ -119,36 +123,40 @@ struct OtAonTimerState {
119
123
uint32_t pclk ;
120
124
};
121
125
122
- static uint32_t
126
+ static uint64_t
123
127
ot_aon_timer_ns_to_ticks (OtAonTimerState * s , uint32_t prescaler , int64_t ns )
124
128
{
125
129
uint64_t ticks = muldiv64 ((uint64_t )ns , s -> pclk , NANOSECONDS_PER_SECOND );
126
- return ( uint32_t )( ticks / (prescaler + 1u ) );
130
+ return ticks / (prescaler + 1u );
127
131
}
128
132
129
133
static int64_t
130
- ot_aon_timer_ticks_to_ns (OtAonTimerState * s , uint32_t prescaler , uint32_t ticks )
134
+ ot_aon_timer_ticks_to_ns (OtAonTimerState * s , uint32_t prescaler , uint64_t ticks )
131
135
{
132
- uint64_t ns = muldiv64 (( uint64_t ) ticks * ( prescaler + 1u ),
133
- NANOSECONDS_PER_SECOND , s -> pclk );
136
+ uint64_t ns =
137
+ muldiv64 ( ticks * ( prescaler + 1u ), NANOSECONDS_PER_SECOND , s -> pclk );
134
138
if (ns > INT64_MAX ) {
135
139
return INT64_MAX ;
136
140
}
137
141
return (int64_t )ns ;
138
142
}
139
143
140
- static uint32_t ot_aon_timer_get_wkup_count (OtAonTimerState * s , uint64_t now )
144
+ static uint64_t ot_aon_timer_get_wkup_count (OtAonTimerState * s , uint64_t now )
141
145
{
142
146
uint32_t prescaler = FIELD_EX32 (s -> regs [R_WKUP_CTRL ], WKUP_CTRL , PRESCALER );
143
- return s -> regs [R_WKUP_COUNT ] +
147
+ uint64_t wkup_count =
148
+ ((uint64_t )s -> regs [R_WKUP_COUNT_HI ] << 32u ) | s -> regs [R_WKUP_COUNT_LO ];
149
+ return wkup_count +
144
150
ot_aon_timer_ns_to_ticks (s , prescaler ,
145
151
(int64_t )(now - s -> wkup_origin_ns ));
146
152
}
147
153
148
154
static uint32_t ot_aon_timer_get_wdog_count (OtAonTimerState * s , uint64_t now )
149
155
{
150
156
return s -> regs [R_WDOG_COUNT ] +
151
- ot_aon_timer_ns_to_ticks (s , 0u , (int64_t )(now - s -> wdog_origin_ns ));
157
+ (uint32_t )
158
+ ot_aon_timer_ns_to_ticks (s , 0u ,
159
+ (int64_t )(now - s -> wdog_origin_ns ));
152
160
}
153
161
154
162
static int64_t ot_aon_timer_compute_next_timeout (OtAonTimerState * s ,
@@ -192,7 +200,6 @@ static void ot_aon_timer_update_irqs(OtAonTimerState *s)
192
200
{
193
201
bool wkup = (bool )(s -> regs [R_INTR_STATE ] & INTR_WKUP_TIMER_EXPIRED_MASK );
194
202
bool bark = (bool )(s -> regs [R_INTR_STATE ] & INTR_WDOG_TIMER_BARK_MASK );
195
-
196
203
trace_ot_aon_timer_irqs (s -> ot_id , wkup , bark , s -> wdog_bite );
197
204
198
205
ibex_irq_set (& s -> irq_wkup , wkup );
@@ -218,8 +225,9 @@ static void ot_aon_timer_rearm_wkup(OtAonTimerState *s, bool reset_origin)
218
225
return ;
219
226
}
220
227
221
- uint32_t count = ot_aon_timer_get_wkup_count (s , now );
222
- uint32_t threshold = s -> regs [R_WKUP_THOLD ];
228
+ uint64_t count = ot_aon_timer_get_wkup_count (s , now );
229
+ uint64_t threshold =
230
+ ((uint64_t )s -> regs [R_WKUP_THOLD_HI ] << 32u ) | s -> regs [R_WKUP_THOLD_LO ];
223
231
224
232
if (count >= threshold ) {
225
233
s -> regs [R_INTR_STATE ] |= INTR_WKUP_TIMER_EXPIRED_MASK ;
@@ -309,7 +317,8 @@ static uint64_t ot_aon_timer_read(void *opaque, hwaddr addr, unsigned size)
309
317
hwaddr reg = R32_OFF (addr );
310
318
switch (reg ) {
311
319
case R_WKUP_CTRL :
312
- case R_WKUP_THOLD :
320
+ case R_WKUP_THOLD_HI :
321
+ case R_WKUP_THOLD_LO :
313
322
case R_WDOG_REGWEN :
314
323
case R_WDOG_CTRL :
315
324
case R_WDOG_BARK_THOLD :
@@ -318,11 +327,18 @@ static uint64_t ot_aon_timer_read(void *opaque, hwaddr addr, unsigned size)
318
327
case R_WKUP_CAUSE :
319
328
val32 = s -> regs [reg ];
320
329
break ;
321
- case R_WKUP_COUNT : {
330
+ case R_WKUP_COUNT_HI : {
331
+ uint64_t now = ot_aon_timer_is_wkup_enabled (s ) ?
332
+ qemu_clock_get_ns (OT_VIRTUAL_CLOCK ) :
333
+ s -> wkup_origin_ns ;
334
+ val32 = (uint32_t )(ot_aon_timer_get_wkup_count (s , now ) >> 32u );
335
+ break ;
336
+ }
337
+ case R_WKUP_COUNT_LO : {
322
338
uint64_t now = ot_aon_timer_is_wkup_enabled (s ) ?
323
339
qemu_clock_get_ns (OT_VIRTUAL_CLOCK ) :
324
340
s -> wkup_origin_ns ;
325
- val32 = ot_aon_timer_get_wkup_count (s , now );
341
+ val32 = ( uint32_t ) ot_aon_timer_get_wkup_count (s , now );
326
342
break ;
327
343
}
328
344
case R_WDOG_COUNT : {
@@ -384,19 +400,23 @@ static void ot_aon_timer_write(void *opaque, hwaddr addr, uint64_t value,
384
400
/* stop timer */
385
401
timer_del (s -> wkup_timer );
386
402
/* save current count */
387
- uint32_t now = qemu_clock_get_ns (OT_VIRTUAL_CLOCK );
388
- s -> regs [R_WKUP_COUNT ] = ot_aon_timer_get_wkup_count (s , now );
403
+ uint64_t now = qemu_clock_get_ns (OT_VIRTUAL_CLOCK );
404
+ uint64_t count = ot_aon_timer_get_wkup_count (s , now );
405
+ s -> regs [R_WKUP_COUNT_HI ] = (uint32_t )(count >> 32u );
406
+ s -> regs [R_WKUP_COUNT_LO ] = (uint32_t )count ;
389
407
s -> wkup_origin_ns = now ;
390
408
}
391
409
}
392
410
break ;
393
411
}
394
- case R_WKUP_THOLD :
395
- s -> regs [R_WKUP_THOLD ] = val32 ;
412
+ case R_WKUP_THOLD_HI :
413
+ case R_WKUP_THOLD_LO :
414
+ s -> regs [reg ] = val32 ;
396
415
ot_aon_timer_rearm_wkup (s , false);
397
416
break ;
398
- case R_WKUP_COUNT :
399
- s -> regs [R_WKUP_COUNT ] = val32 ;
417
+ case R_WKUP_COUNT_HI :
418
+ case R_WKUP_COUNT_LO :
419
+ s -> regs [reg ] = val32 ;
400
420
ot_aon_timer_rearm_wkup (s , true);
401
421
break ;
402
422
case R_WDOG_REGWEN :
0 commit comments