@@ -120,12 +120,12 @@ static QTAILQ_HEAD(, AppleA13Cluster) clusters =
120120static uint64_t ipi_cr = kDeferredIPITimerDefault ;
121121static QEMUTimer * ipicr_timer = NULL ;
122122
123- bool apple_a13_is_asleep (AppleA13State * acpu )
123+ bool apple_a13_is_asleep (const AppleA13State * acpu )
124124{
125125 return CPU (acpu )-> halted ;
126126}
127127
128- bool apple_a13_is_off (AppleA13State * acpu )
128+ bool apple_a13_is_off (const AppleA13State * acpu )
129129{
130130 return acpu -> parent_obj .power_state == PSCI_OFF ;
131131}
@@ -213,15 +213,21 @@ static void apple_a13_cluster_cpreg_write(CPUARMState *env,
213213}
214214
215215/* Deliver IPI */
216- static void apple_a13_cluster_deliver_ipi ( AppleA13Cluster * c , uint64_t cpu_id ,
217- uint64_t src_cpu , uint64_t flag )
216+ static void apple_a13_deliver_ipi ( AppleA13State * cpu , uint64_t src_cpu ,
217+ uint64_t flag )
218218{
219- if (c -> cpus [ cpu_id ] -> ipi_sr ) {
219+ if (cpu -> ipi_sr ) {
220220 return ;
221221 }
222222
223- c -> cpus [cpu_id ]-> ipi_sr = 1LL | (src_cpu << IPI_SR_SRC_CPU_SHIFT ) | flag ;
224- qemu_irq_raise (c -> cpus [cpu_id ]-> fast_ipi );
223+ cpu -> ipi_sr = 1LL | (src_cpu << IPI_SR_SRC_CPU_SHIFT ) | flag ;
224+ qemu_irq_raise (cpu -> fast_ipi );
225+ }
226+
227+ static void apple_a13_cluster_deliver_ipi (AppleA13Cluster * c , uint64_t cpu_id ,
228+ uint64_t src_cpu , uint64_t flag )
229+ {
230+ apple_a13_deliver_ipi (c -> cpus [cpu_id ], src_cpu , flag );
225231}
226232
227233static int apple_a13_cluster_pre_save (void * opaque )
@@ -248,17 +254,14 @@ static void apple_a13_cluster_reset(DeviceState *dev)
248254static int add_cpu_to_cluster (Object * obj , void * opaque )
249255{
250256 AppleA13Cluster * cluster = opaque ;
251- CPUState * cpu = (CPUState * )object_dynamic_cast (obj , TYPE_CPU );
252257 AppleA13State * acpu =
253258 (AppleA13State * )object_dynamic_cast (obj , TYPE_APPLE_A13 );
254259
255- if (!cpu ) {
256- return 0 ;
257- }
258- cpu -> cluster_index = cluster -> parent_obj .cluster_id ;
259260 if (!acpu ) {
260261 return 0 ;
261262 }
263+
264+ acpu -> parent_obj .parent_obj .cluster_index = cluster -> parent_obj .cluster_id ;
262265 cluster -> cpus [acpu -> cpu_id ] = acpu ;
263266 return 0 ;
264267}
@@ -271,28 +274,40 @@ static void apple_a13_cluster_realize(DeviceState *dev, Error **errp)
271274
272275static void apple_a13_cluster_tick (AppleA13Cluster * c )
273276{
274- int i ;
275- int j ;
277+ uint32_t on = 0 , awake = 0 ;
276278
277- for (i = 0 ; i < A13_MAX_CPU ; i ++ ) { /* source */
278- for (j = 0 ; j < A13_MAX_CPU ; j ++ ) { /* target */
279- if (c -> cpus [j ] && c -> deferredIPI [i ][j ] &&
280- !apple_a13_is_off (c -> cpus [j ])) {
281- apple_a13_cluster_deliver_ipi (c , j , i , IPI_RR_TYPE_DEFERRED );
282- break ;
283- }
279+ for (uint32_t i = 0 ; i < A13_MAX_CPU ; ++ i ) {
280+ const AppleA13State * cpu = c -> cpus [i ];
281+ if (!cpu || apple_a13_is_off (cpu )) {
282+ continue ;
283+ }
284+ on |= BIT32 (i );
285+ if (!apple_a13_is_asleep (cpu )) {
286+ awake |= BIT32 (i );
284287 }
285288 }
286289
287- for (i = 0 ; i < A13_MAX_CPU ; i ++ ) { /* source */
288- for (j = 0 ; j < A13_MAX_CPU ; j ++ ) { /* target */
289- if (c -> cpus [j ] && c -> noWakeIPI [i ][j ] &&
290- !apple_a13_is_asleep (c -> cpus [j ]) &&
291- !apple_a13_is_off (c -> cpus [j ])) {
292- apple_a13_cluster_deliver_ipi (c , j , i , IPI_RR_TYPE_NOWAKE );
293- break ;
294- }
290+ if (!on ) {
291+ return ;
292+ }
293+
294+ for (uint32_t src = 0 ; src < A13_MAX_CPU ; ++ src ) {
295+ if (!c -> cpus [src ]) {
296+ continue ;
295297 }
298+
299+ const uint32_t noWakeCandidates = c -> noWakeIPI [src ] & awake ;
300+ const uint32_t candidates =
301+ noWakeCandidates | (c -> deferredIPI [src ] & on );
302+ if (!candidates ) {
303+ continue ;
304+ }
305+
306+ const uint32_t dest = ctz32 (candidates );
307+ const uint32_t type = (noWakeCandidates & BIT32 (dest )) ?
308+ IPI_RR_TYPE_NOWAKE :
309+ IPI_RR_TYPE_DEFERRED ;
310+ apple_a13_cluster_deliver_ipi (c , dest , src , type );
296311 }
297312}
298313
@@ -310,14 +325,14 @@ static void apple_a13_cluster_ipicr_tick(void *opaque)
310325
311326static void apple_a13_cluster_reset_handler (void * opaque )
312327{
328+ ipi_cr = kDeferredIPITimerDefault ;
313329 if (ipicr_timer ) {
314330 timer_del (ipicr_timer );
315- ipicr_timer = NULL ;
331+ } else {
332+ ipicr_timer = timer_new_ns (QEMU_CLOCK_VIRTUAL ,
333+ apple_a13_cluster_ipicr_tick , NULL );
316334 }
317- ipicr_timer =
318- timer_new_ns (QEMU_CLOCK_VIRTUAL , apple_a13_cluster_ipicr_tick , NULL );
319- timer_mod_ns (ipicr_timer , qemu_clock_get_ns (QEMU_CLOCK_VIRTUAL ) +
320- kDeferredIPITimerDefault );
335+ timer_mod_ns (ipicr_timer , qemu_clock_get_ns (QEMU_CLOCK_VIRTUAL ) + ipi_cr );
321336}
322337
323338static void apple_a13_cluster_instance_init (Object * obj )
@@ -339,19 +354,18 @@ static void apple_a13_ipi_rr_local(CPUARMState *env, const ARMCPRegInfo *ri,
339354
340355 uint32_t phys_id = (value & 0xFF ) | (acpu -> cluster_id << 8 );
341356 AppleA13Cluster * c = apple_a13_find_cluster (acpu -> cluster_id );
342- uint32_t cpu_id = -1U ;
343- int i ;
344-
345- for (i = 0 ; i < A13_MAX_CPU ; i ++ ) {
346- if (c -> cpus [i ]) {
347- if (c -> cpus [i ]-> phys_id == phys_id ) {
348- cpu_id = i ;
349- break ;
350- }
357+ uint32_t dst_cpu_id = -1U ;
358+ AppleA13State * dst_acpu ;
359+
360+ for (uint32_t i = 0 ; i < A13_MAX_CPU ; i ++ ) {
361+ if (c -> cpus [i ] != NULL && c -> cpus [i ]-> phys_id == phys_id ) {
362+ dst_cpu_id = i ;
363+ dst_acpu = c -> cpus [dst_cpu_id ];
364+ break ;
351365 }
352366 }
353367
354- if (cpu_id == -1U || c -> cpus [ cpu_id ] == NULL ) {
368+ if (dst_cpu_id == -1U ) {
355369 qemu_log_mask (LOG_GUEST_ERROR ,
356370 "CPU %x failed to send fast IPI to local CPU %x: value: "
357371 "0x" HWADDR_FMT_plx "\n" ,
@@ -361,27 +375,25 @@ static void apple_a13_ipi_rr_local(CPUARMState *env, const ARMCPRegInfo *ri,
361375
362376 switch (value & IPI_RR_TYPE_MASK ) {
363377 case IPI_RR_TYPE_NOWAKE :
364- if (apple_a13_is_asleep (c -> cpus [ cpu_id ] )) {
365- c -> noWakeIPI [acpu -> cpu_id ][ cpu_id ] = 1 ;
378+ if (apple_a13_is_asleep (dst_acpu )) {
379+ c -> noWakeIPI [acpu -> cpu_id ] |= BIT32 ( dst_cpu_id ) ;
366380 } else {
367- apple_a13_cluster_deliver_ipi ( c , cpu_id , acpu -> cpu_id ,
368- IPI_RR_TYPE_IMMEDIATE );
381+ apple_a13_deliver_ipi ( dst_acpu , acpu -> cpu_id ,
382+ IPI_RR_TYPE_IMMEDIATE );
369383 }
370384 break ;
371385 case IPI_RR_TYPE_DEFERRED :
372- c -> deferredIPI [acpu -> cpu_id ][ cpu_id ] = 1 ;
386+ c -> deferredIPI [acpu -> cpu_id ] |= BIT32 ( dst_cpu_id ) ;
373387 break ;
374388 case IPI_RR_TYPE_RETRACT :
375- c -> deferredIPI [acpu -> cpu_id ][ cpu_id ] = 0 ;
376- c -> noWakeIPI [acpu -> cpu_id ][ cpu_id ] = 0 ;
389+ c -> deferredIPI [acpu -> cpu_id ] &= ~ BIT32 ( dst_cpu_id ) ;
390+ c -> noWakeIPI [acpu -> cpu_id ] &= ~ BIT32 ( dst_cpu_id ) ;
377391 break ;
378392 case IPI_RR_TYPE_IMMEDIATE :
379- apple_a13_cluster_deliver_ipi (c , cpu_id , acpu -> cpu_id ,
380- IPI_RR_TYPE_IMMEDIATE );
393+ apple_a13_deliver_ipi (dst_acpu , acpu -> cpu_id , IPI_RR_TYPE_IMMEDIATE );
381394 break ;
382395 default :
383396 g_assert_not_reached ();
384- break ;
385397 }
386398}
387399
@@ -392,27 +404,24 @@ static void apple_a13_ipi_rr_global(CPUARMState *env, const ARMCPRegInfo *ri,
392404 AppleA13State * acpu =
393405 container_of (env_archcpu (env ), AppleA13State , parent_obj );
394406 uint32_t cluster_id = (value >> IPI_RR_TARGET_CLUSTER_SHIFT ) & 0xFF ;
395- AppleA13Cluster * c = apple_a13_find_cluster (cluster_id );
396-
397- if (!c ) {
407+ AppleA13Cluster * cluster = apple_a13_find_cluster (cluster_id );
408+ if (!cluster ) {
398409 return ;
399410 }
400411
401412 uint32_t phys_id = (value & 0xFF ) | (cluster_id << 8 );
402- uint32_t cpu_id = -1 ;
403- int i ;
413+ uint32_t dst_cpu_id = -1 ;
414+ AppleA13State * dst_acpu ;
404415
405- for (i = 0 ; i < A13_MAX_CPU ; i ++ ) {
406- if (c -> cpus [i ] == NULL ) {
407- continue ;
408- }
409- if (c -> cpus [i ]-> phys_id == phys_id ) {
410- cpu_id = i ;
416+ for (uint32_t i = 0 ; i < A13_MAX_CPU ; i ++ ) {
417+ if (cluster -> cpus [i ] != NULL && cluster -> cpus [i ]-> phys_id == phys_id ) {
418+ dst_cpu_id = i ;
419+ dst_acpu = cluster -> cpus [dst_cpu_id ];
411420 break ;
412421 }
413422 }
414423
415- if (cpu_id == -1U || c -> cpus [ cpu_id ] == NULL ) {
424+ if (dst_cpu_id == -1U ) {
416425 qemu_log_mask (LOG_GUEST_ERROR ,
417426 "CPU %x failed to send fast IPI to global CPU %x: value: "
418427 "0x" HWADDR_FMT_plx "\n" ,
@@ -422,27 +431,25 @@ static void apple_a13_ipi_rr_global(CPUARMState *env, const ARMCPRegInfo *ri,
422431
423432 switch (value & IPI_RR_TYPE_MASK ) {
424433 case IPI_RR_TYPE_NOWAKE :
425- if (apple_a13_is_asleep (c -> cpus [ cpu_id ] )) {
426- c -> noWakeIPI [acpu -> cpu_id ][ cpu_id ] = 1 ;
434+ if (apple_a13_is_asleep (dst_acpu )) {
435+ cluster -> noWakeIPI [acpu -> cpu_id ] |= BIT32 ( dst_cpu_id ) ;
427436 } else {
428- apple_a13_cluster_deliver_ipi ( c , cpu_id , acpu -> cpu_id ,
429- IPI_RR_TYPE_IMMEDIATE );
437+ apple_a13_deliver_ipi ( dst_acpu , acpu -> cpu_id ,
438+ IPI_RR_TYPE_IMMEDIATE );
430439 }
431440 break ;
432441 case IPI_RR_TYPE_DEFERRED :
433- c -> deferredIPI [acpu -> cpu_id ][ cpu_id ] = 1 ;
442+ cluster -> deferredIPI [acpu -> cpu_id ] |= BIT32 ( dst_cpu_id ) ;
434443 break ;
435444 case IPI_RR_TYPE_RETRACT :
436- c -> deferredIPI [acpu -> cpu_id ][ cpu_id ] = 0 ;
437- c -> noWakeIPI [acpu -> cpu_id ][ cpu_id ] = 0 ;
445+ cluster -> deferredIPI [acpu -> cpu_id ] &= ~ BIT32 ( dst_cpu_id ) ;
446+ cluster -> noWakeIPI [acpu -> cpu_id ] &= ~ BIT32 ( dst_cpu_id ) ;
438447 break ;
439448 case IPI_RR_TYPE_IMMEDIATE :
440- apple_a13_cluster_deliver_ipi (c , cpu_id , acpu -> cpu_id ,
441- IPI_RR_TYPE_IMMEDIATE );
449+ apple_a13_deliver_ipi (dst_acpu , acpu -> cpu_id , IPI_RR_TYPE_IMMEDIATE );
442450 break ;
443451 default :
444452 g_assert_not_reached ();
445- break ;
446453 }
447454}
448455
@@ -469,10 +476,10 @@ static void apple_a13_ipi_write_sr(CPUARMState *env, const ARMCPRegInfo *ri,
469476
470477 switch (value & IPI_RR_TYPE_MASK ) {
471478 case IPI_RR_TYPE_NOWAKE :
472- c -> noWakeIPI [src_cpu ][ acpu -> cpu_id ] = 0 ;
479+ c -> noWakeIPI [src_cpu ] &= ~ BIT32 ( acpu -> cpu_id ) ;
473480 break ;
474481 case IPI_RR_TYPE_DEFERRED :
475- c -> deferredIPI [src_cpu ][ acpu -> cpu_id ] = 0 ;
482+ c -> deferredIPI [src_cpu ] &= ~ BIT32 ( acpu -> cpu_id ) ;
476483 break ;
477484 default :
478485 break ;
@@ -482,7 +489,7 @@ static void apple_a13_ipi_write_sr(CPUARMState *env, const ARMCPRegInfo *ri,
482489/* Read deferred interrupt timeout (global) */
483490static uint64_t apple_a13_ipi_read_cr (CPUARMState * env , const ARMCPRegInfo * ri )
484491{
485- uint64_t abstime ;
492+ uint64_t abstime = 0 ;
486493
487494 nanoseconds_to_absolutetime (ipi_cr , & abstime );
488495 return abstime ;
@@ -492,18 +499,18 @@ static uint64_t apple_a13_ipi_read_cr(CPUARMState *env, const ARMCPRegInfo *ri)
492499static void apple_a13_ipi_write_cr (CPUARMState * env , const ARMCPRegInfo * ri ,
493500 uint64_t value )
494501{
495- uint64_t nanosec = kDeferredIPITimerDefault ;
496- uint64_t ct ;
502+ uint64_t nanosec = 0 ;
503+ uint64_t ct = qemu_clock_get_ns ( QEMU_CLOCK_VIRTUAL ) ;
497504
498505 if (value != 0 ) {
499- absolutetime_to_nanoseconds (value , & nanosec );
500- if (nanosec == 0 ) {
501- nanosec = kDeferredIPITimerDefault ;
502- }
506+ absolutetime_to_nanoseconds (value & 0xFFFF , & nanosec );
503507 }
504508
505- ct = qemu_clock_get_ns (QEMU_CLOCK_VIRTUAL );
506- timer_mod_ns (ipicr_timer , ((ct / ipi_cr ) * ipi_cr ) + nanosec );
509+ if (nanosec == 0 ) {
510+ timer_del (ipicr_timer );
511+ } else {
512+ timer_mod_ns (ipicr_timer , ct + nanosec );
513+ }
507514 ipi_cr = nanosec ;
508515}
509516
@@ -751,7 +758,7 @@ static const Property apple_a13_cluster_properties[] = {
751758};
752759
753760static const VMStateDescription vmstate_apple_a13 = {
754- .name = "apple_a13 " ,
761+ .name = "AppleA13State " ,
755762 .version_id = 1 ,
756763 .minimum_version_id = 1 ,
757764 .fields =
@@ -799,18 +806,15 @@ static const VMStateDescription vmstate_apple_a13 = {
799806};
800807
801808static const VMStateDescription vmstate_apple_a13_cluster = {
802- .name = "apple_a13_cluster " ,
809+ .name = "AppleA13Cluster " ,
803810 .version_id = 1 ,
804811 .minimum_version_id = 1 ,
805812 .pre_save = apple_a13_cluster_pre_save ,
806813 .post_load = apple_a13_cluster_post_load ,
807814 .fields =
808815 (const VMStateField []){
809- VMSTATE_UINT32_2DARRAY (deferredIPI , AppleA13Cluster , A13_MAX_CPU ,
810- A13_MAX_CPU ),
811- VMSTATE_UINT32_2DARRAY (noWakeIPI , AppleA13Cluster , A13_MAX_CPU ,
812- A13_MAX_CPU ),
813- VMSTATE_UINT64 (tick , AppleA13Cluster ),
816+ VMSTATE_UINT32_ARRAY (deferredIPI , AppleA13Cluster , A13_MAX_CPU ),
817+ VMSTATE_UINT32_ARRAY (noWakeIPI , AppleA13Cluster , A13_MAX_CPU ),
814818 VMSTATE_UINT64 (ipi_cr , AppleA13Cluster ),
815819 VMSTATE_A13_CLUSTER_CPREG (CTRR_A_LWR_EL1 ),
816820 VMSTATE_A13_CLUSTER_CPREG (CTRR_A_UPR_EL1 ),
0 commit comments