-/* $OpenBSD: cpu.c,v 1.95 2023/06/15 22:18:07 cheloha Exp $ */
+/* $OpenBSD: cpu.c,v 1.96 2023/07/13 08:33:36 kettenis Exp $ */
/*
* Copyright (c) 2016 Dale Rahn <drahn@dalerahn.com>
void cpu_hatch_secondary(void);
void cpu_hatch_secondary_spin(void);
+void cpu_suspend_cycle(void);
+
void
cpu_boot_secondary_processors(void)
{
ci->ci_psci_suspend_param = 0;
} else
#endif
- __asm volatile("wfi");
+ cpu_suspend_cycle();
count++;
}
void cpu_hatch_primary(void);
+void (*cpu_suspend_cycle_fcn)(void) = cpu_wfi;
label_t cpu_suspend_jmpbuf;
int cpu_suspended;
+void
+cpu_suspend_cycle(void)
+{
+ cpu_suspend_cycle_fcn();
+}
+
void
cpu_init_primary(void)
{
ci->ci_psci_suspend_param = 0;
} else
#endif
- __asm volatile("wfi");
+ cpu_suspend_cycle();
count++;
}
-/* $OpenBSD: cpufunc_asm.S,v 1.7 2020/11/20 21:48:33 patrick Exp $ */
+/* $OpenBSD: cpufunc_asm.S,v 1.8 2023/07/13 08:33:36 kettenis Exp $ */
/*-
* Copyright (c) 2014 Robin Randhawa
* Copyright (c) 2015 The FreeBSD Foundation
RETGUARD_CHECK(cpu_icache_sync_range, x15)
ret
END(cpu_icache_sync_range)
+
+ENTRY(cpu_wfi)
+ RETGUARD_SETUP(cpu_wfi, x15)
+ dsb sy
+ wfi
+ RETGUARD_CHECK(cpu_wfi, x15)
+ ret
+END(cpu_wfi)
+
+ENTRY(aplcpu_deep_wfi)
+ RETGUARD_SETUP(aplcpu_deep_wfi, x15)
+
+ stp x30, x15, [sp, #-16]!
+ stp x28, x29, [sp, #-16]!
+ stp x26, x27, [sp, #-16]!
+ stp x24, x25, [sp, #-16]!
+ stp x22, x23, [sp, #-16]!
+ stp x20, x21, [sp, #-16]!
+ stp x18, x19, [sp, #-16]!
+
+ mrs x0, daif
+ str x0, [sp, #-16]!
+ msr daifset, #3
+
+ mrs x0, s3_5_c15_c5_0
+ orr x0, x0, #(3 << 24)
+ msr s3_5_c15_c5_0, x0
+
+ dsb sy
+ wfi
+
+ mrs x0, s3_5_c15_c5_0
+ bic x0, x0, #(1 << 24)
+ msr s3_5_c15_c5_0, x0
+
+ ldr x0, [sp], #16
+ msr daif, x0
+
+ ldp x18, x19, [sp], #16
+ ldp x20, x21, [sp], #16
+ ldp x22, x23, [sp], #16
+ ldp x24, x25, [sp], #16
+ ldp x26, x27, [sp], #16
+ ldp x28, x29, [sp], #16
+ ldp x30, x15, [sp], #16
+
+ RETGUARD_CHECK(aplcpu_deep_wfi, x15)
+ ret
+END(aplcpu_deep_wfi)
-/* $OpenBSD: machdep.c,v 1.82 2023/06/10 19:30:48 kettenis Exp $ */
+/* $OpenBSD: machdep.c,v 1.83 2023/07/13 08:33:36 kettenis Exp $ */
/*
* Copyright (c) 2014 Patrick Wildt <patrick@blueri.se>
* Copyright (c) 2021 Mark Kettenis <kettenis@openbsd.org>
{
}
+void (*cpu_idle_cycle_fcn)(void) = cpu_wfi;
+
void
cpu_idle_cycle(void)
{
enable_irq_daif();
- __asm volatile("dsb sy" ::: "memory");
- __asm volatile("wfi");
+ cpu_idle_cycle_fcn();
}
void
-/* $OpenBSD: aplcpu.c,v 1.7 2023/05/09 10:13:23 kettenis Exp $ */
+/* $OpenBSD: aplcpu.c,v 1.8 2023/07/13 08:33:36 kettenis Exp $ */
/*
* Copyright (c) 2022 Mark Kettenis <kettenis@openbsd.org>
*
#define DVFS_T8112_STATUS_CUR_PS_MASK (0x1f << 5)
#define DVFS_T8112_STATUS_CUR_PS_SHIFT 5
+#define APLCPU_DEEP_WFI_LATENCY 10 /* microseconds */
+
struct opp {
uint64_t opp_hz;
uint32_t opp_level;
int aplcpu_clockspeed(int *);
void aplcpu_setperf(int level);
void aplcpu_refresh_sensors(void *);
+void aplcpu_idle_cycle();
+void aplcpu_deep_wfi(void);
int
aplcpu_match(struct device *parent, void *match, void *aux)
sensordev_install(&sc->sc_sensordev);
sensor_task_register(sc, aplcpu_refresh_sensors, 1);
+ cpu_idle_cycle_fcn = aplcpu_idle_cycle;
+ cpu_suspend_cycle_fcn = aplcpu_deep_wfi;
cpu_cpuspeed = aplcpu_clockspeed;
cpu_setperf = aplcpu_setperf;
return;
return;
count = 0;
- for (child = OF_child(node); child != 0; child = OF_peer(child)) {
- if (OF_getproplen(child, "turbo-mode") == 0)
- continue;
+ for (child = OF_child(node); child != 0; child = OF_peer(child))
count++;
- }
if (count == 0)
return;
count = 0;
for (child = OF_child(node); child != 0; child = OF_peer(child)) {
- if (OF_getproplen(child, "turbo-mode") == 0)
- continue;
opp_hz = OF_getpropint64(child, "opp-hz", 0);
opp_level = OF_getpropint(child, "opp-level", 0);
}
}
}
+
+void
+aplcpu_idle_cycle(void)
+{
+ struct cpu_info *ci = curcpu();
+ struct timeval start, stop;
+ u_long itime;
+
+ microuptime(&start);
+
+ if (ci->ci_prev_sleep > 3 * APLCPU_DEEP_WFI_LATENCY)
+ aplcpu_deep_wfi();
+ else
+ cpu_wfi();
+
+ microuptime(&stop);
+ timersub(&stop, &start, &stop);
+ itime = stop.tv_sec * 1000000 + stop.tv_usec;
+
+ ci->ci_last_itime = itime;
+ itime >>= 1;
+ ci->ci_prev_sleep = (ci->ci_prev_sleep + (ci->ci_prev_sleep >> 1)
+ + itime) >> 1;
+}
-/* $OpenBSD: cpu.h,v 1.36 2023/06/10 19:30:48 kettenis Exp $ */
+/* $OpenBSD: cpu.h,v 1.37 2023/07/13 08:33:36 kettenis Exp $ */
/*
* Copyright (c) 2016 Dale Rahn <drahn@dalerahn.com>
*
volatile int ci_opp_max;
uint32_t ci_cpu_supply;
+ u_long ci_prev_sleep;
+ u_long ci_last_itime;
+
#ifdef MULTIPROCESSOR
struct srp_hazard ci_srp_hazards[SRP_HAZARD_NUM];
volatile int ci_flags;
int cpu_suspend_primary(void);
void cpu_resume_secondary(struct cpu_info *);
+extern void (*cpu_idle_cycle_fcn)(void);
+extern void (*cpu_suspend_cycle_fcn)(void);
+
+void cpu_wfi(void);
+
void delay (unsigned);
#define DELAY(x) delay(x)