484
}
485
}
486
487
-void HELPER(wfe)(CPUARMState *env)
487
+#ifndef CONFIG_USER_ONLY
488
+/*
489
+ * Event Stream events don't do anything apart from wake up sleeping
490
+ * cores. These helpers calculate the next event stream event time so
491
+ * the WFE helper can decide when its next wake up tick will be.
492
+ */
493
+static int64_t gt_recalc_one_evt(CPUARMState *env, uint32_t control, uint64_t offset)
494
+{
495
+ ARMCPU *cpu = env_archcpu(env);
496
+ bool evnten = FIELD_EX32(control, CNTxCTL, EVNTEN);
497
+
498
+ if (evnten) {
499
+ int evnti = FIELD_EX32(control, CNTxCTL, EVNTI);
500
+ bool evntis = FIELD_EX32(control, CNTxCTL, EVNTIS);
501
+ bool evntdir = FIELD_EX32(control, CNTxCTL, EVNTDIR);
502
+ /*
503
+ * To figure out when the next event timer should fire we need
504
+ * to calculate which bit of the counter we want to flip and
505
+ * which transition counts.
506
+ *
507
+ * So we calculate 1 << bit - current lower bits and then add
508
+ * 1 << bit if the bit needs to flip twice to meet evntdir
509
+ */
510
+ int bit = evntis ? evnti + 8 : evnti;
511
+ uint64_t count = gt_get_countervalue(env) - offset;
512
+ uint64_t target_bit = BIT_ULL(bit);
513
+ uint64_t lower_bits = MAKE_64BIT_MASK(0, bit - 1);
514
+ uint64_t next_tick = target_bit - (count & lower_bits);
515
+ uint64_t abstick;
516
+
517
+ /* do we need to bit flip twice? */
518
+ if (((count & target_bit) != 0) ^ evntdir) {
519
+ next_tick += target_bit;
520
+ }
521
+
522
+ /*
523
+ * Note that the desired next expiry time might be beyond the
524
+ * signed-64-bit range of a QEMUTimer -- in this case we just
525
+ * set the timer for as far in the future as possible. When the
526
+ * timer expires we will reset the timer for any remaining period.
527
+ */
528
+ if (uadd64_overflow(next_tick, offset, &abstick)) {
529
+ abstick = UINT64_MAX;
530
+ }
531
+ if (abstick > INT64_MAX / gt_cntfrq_period_ns(cpu)) {
532
+ return INT64_MAX;
533
+ } else {
534
+ return abstick;
535
+ }
536
+ }
537
+
538
+ return -1;
539
+}
540
+
541
+/*
542
+ * Calculate the next event stream time and return it. Returns -1 if
543
+ * no event streams are enabled. It is up to the WFE helpers to decide
544
+ * on the next time.
545
+ */
546
+static int64_t gt_calc_next_event_stream(CPUARMState *env)
547
+{
548
+ ARMCPU *cpu = env_archcpu(env);
549
+ uint64_t hcr = arm_hcr_el2_eff(env);
550
+ int64_t next_time = -1;
551
+ uint64_t offset;
552
+
553
+ /* Unless we are missing EL2 this can generate events */
554
+ if (arm_feature(env, ARM_FEATURE_EL2)) {
555
+ offset = gt_direct_access_timer_offset(env, GTIMER_PHYS);
556
+ next_time = gt_recalc_one_evt(env, env->cp15.cnthctl_el2, offset);
557
+ }
558
+
559
+ /* Event stream events from virtual counter enabled? */
560
+ if (!cpu_isar_feature(aa64_vh, cpu) ||
561
+ !((hcr & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE))) {
562
+ int64_t next_virt_time;
563
+ offset = gt_direct_access_timer_offset(env, GTIMER_VIRT);
564
+ next_virt_time = gt_recalc_one_evt(env, env->cp15.c14_cntkctl, offset);
565
+
566
+ /* is this earlier than the next physical event? */
567
+ if (next_virt_time > 0) {
568
+ if (next_time < 0 || next_virt_time < next_time) {
569
+ next_time = next_virt_time;
570
+ }
571
+ }
572
+ }
573
+
574
+ return next_time;
575
+}
576
+#endif
577
+
578
+void HELPER(wfe)(CPUARMState *env, uint32_t insn_len)
579
{
580
#ifdef CONFIG_USER_ONLY
581
/*
587
#else
588
/*
589
* WFE (Wait For Event) is a hint instruction.
499
- * For Cortex-M (M-profile), we implement the strict architectural behavior:
590
+ *
591
* 1. Check the Event Register (set by SEV or SEVONPEND).
592
* 2. If set, clear it and continue (consume the event).
593
*/
503
- if (arm_feature(env, ARM_FEATURE_M)) {
504
- CPUState *cs = env_cpu(env);
594
+ CPUState *cs = env_cpu(env);
595
+ ARMCPU *cpu = env_archcpu(env);
596
+ uint32_t excp;
597
+ int target_el;
598
506
- if (env->event_register) {
507
- env->event_register = false;
508
- return;
599
+ if (qatomic_xchg(&env->event_register, false)) {
600
+ return;
601
+ }
602
+
603
+ /* We might sleep, so now we check to see if we should trap */
604
+ target_el = check_wfx_trap(env, true, &excp);
605
+ if (target_el) {
606
+ if (env->aarch64) {
607
+ env->pc -= insn_len;
608
+ } else {
609
+ env->regs[15] -= insn_len;
610
}
611
+ raise_exception(env, excp, syn_wfx(1, 0xe, 0, false, WFE, insn_len == 2),
612
+ target_el);
613
+ }
614
511
- env->halt_reason = HALT_WFE;
512
- cs->exception_index = EXCP_HLT;
513
- cs->halted = 1;
514
- cpu_loop_exit(cs);
515
- } else {
516
- /*
517
- * For A-profile and others, we rely on the existing "yield" behavior.
518
- * Don't actually halt the CPU, just yield back to top
519
- * level loop. This is not going into a "low power state"
520
- * (ie halting until some event occurs), so we never take
521
- * a configurable trap to a different exception level
522
- */
523
- HELPER(yield)(env);
615
+ /*
616
+ * If the CPU has entered the exclusive region we could sleep
617
+ * until the global monitor moves from Exclusive to Open Access.
618
+ * However it would be expensive for QEMU to fully model the
619
+ * global monitor and not doing so would potentially trigger
620
+ * deadlocks in WFE enabled locking code. However as WFE is a hint
621
+ * instruction the architecture allows for the PE to leave
622
+ * low-power state for any reason. QEMU chooses to treat being in
623
+ * an exclusive region as such and return directly.
624
+ */
625
+ if (env->exclusive_addr != -1) {
626
+ return;
627
}
628
+
629
+ /* For A-profile we also can be woken by the event stream */
630
+ if (cpu->wfxt_timer) {
631
+ int64_t next_event = gt_calc_next_event_stream(env);
632
+ if (next_event > 0) {
633
+ timer_mod(cpu->wfxt_timer, next_event);
634
+ }
635
+ }
636
+
637
+ env->halt_reason = HALT_WFE;
638
+ cs->exception_index = EXCP_HLT;
639
+ cs->halted = 1;
640
+ cpu_loop_exit(cs);
641
#endif
642
}
643