Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) #ifndef _ASM_X86_MWAIT_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) #define _ASM_X86_MWAIT_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/sched/idle.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <asm/cpufeature.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <asm/nospec-branch.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #define MWAIT_SUBSTATE_MASK		0xf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #define MWAIT_CSTATE_MASK		0xf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #define MWAIT_SUBSTATE_SIZE		4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #define MWAIT_HINT2CSTATE(hint)		(((hint) >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #define MWAIT_HINT2SUBSTATE(hint)	((hint) & MWAIT_CSTATE_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #define CPUID_MWAIT_LEAF		5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #define CPUID5_ECX_EXTENSIONS_SUPPORTED 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #define CPUID5_ECX_INTERRUPT_BREAK	0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define MWAIT_ECX_INTERRUPT_BREAK	0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define MWAITX_ECX_TIMER_ENABLE		BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define MWAITX_MAX_WAIT_CYCLES		UINT_MAX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define MWAITX_DISABLE_CSTATES		0xf0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define TPAUSE_C01_STATE		1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define TPAUSE_C02_STATE		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) static inline void __monitor(const void *eax, unsigned long ecx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 			     unsigned long edx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	/* "monitor %eax, %ecx, %edx;" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	asm volatile(".byte 0x0f, 0x01, 0xc8;"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 		     :: "a" (eax), "c" (ecx), "d"(edx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) static inline void __monitorx(const void *eax, unsigned long ecx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 			      unsigned long edx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	/* "monitorx %eax, %ecx, %edx;" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	asm volatile(".byte 0x0f, 0x01, 0xfa;"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		     :: "a" (eax), "c" (ecx), "d"(edx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) static inline void __mwait(unsigned long eax, unsigned long ecx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	mds_idle_clear_cpu_buffers();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	/* "mwait %eax, %ecx;" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	asm volatile(".byte 0x0f, 0x01, 0xc9;"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		     :: "a" (eax), "c" (ecx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  * MWAITX allows for a timer expiration to get the core out a wait state in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  * addition to the default MWAIT exit condition of a store appearing at a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  * monitored virtual address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)  * Registers:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)  * MWAITX ECX[1]: enable timer if set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)  * MWAITX EBX[31:0]: max wait time expressed in SW P0 clocks. The software P0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)  * frequency is the same as the TSC frequency.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)  * Below is a comparison between MWAIT and MWAITX on AMD processors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)  *                 MWAIT                           MWAITX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  * opcode          0f 01 c9           |            0f 01 fb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)  * ECX[0]                  value of RFLAGS.IF seen by instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)  * ECX[1]          unused/#GP if set  |            enable timer if set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)  * ECX[31:2]                     unused/#GP if set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  * EAX                           unused (reserve for hint)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  * EBX[31:0]       unused             |            max wait time (P0 clocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)  *                 MONITOR                         MONITORX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)  * opcode          0f 01 c8           |            0f 01 fa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)  * EAX                     (logical) address to monitor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)  * ECX                     #GP if not zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) static inline void __mwaitx(unsigned long eax, unsigned long ebx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 			    unsigned long ecx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	/* No MDS buffer clear as this is AMD/HYGON only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	/* "mwaitx %eax, %ebx, %ecx;" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	asm volatile(".byte 0x0f, 0x01, 0xfb;"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		     :: "a" (eax), "b" (ebx), "c" (ecx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) static inline void __sti_mwait(unsigned long eax, unsigned long ecx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	mds_idle_clear_cpu_buffers();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	/* "mwait %eax, %ecx;" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	asm volatile("sti; .byte 0x0f, 0x01, 0xc9;"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		     :: "a" (eax), "c" (ecx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)  * This uses new MONITOR/MWAIT instructions on P4 processors with PNI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)  * which can obviate IPI to trigger checking of need_resched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)  * We execute MONITOR against need_resched and enter optimized wait state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)  * through MWAIT. Whenever someone changes need_resched, we would be woken
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)  * up from MWAIT (without an IPI).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)  * New with Core Duo processors, MWAIT can take some hints based on CPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)  * capability.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static inline void mwait_idle_with_hints(unsigned long eax, unsigned long ecx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	if (static_cpu_has_bug(X86_BUG_MONITOR) || !current_set_polling_and_test()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		if (static_cpu_has_bug(X86_BUG_CLFLUSH_MONITOR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 			mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 			clflush((void *)&current_thread_info()->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 			mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		__monitor((void *)&current_thread_info()->flags, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		if (!need_resched())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 			__mwait(eax, ecx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	current_clr_polling();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)  * Caller can specify whether to enter C0.1 (low latency, less
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  * power saving) or C0.2 state (saves more power, but longer wakeup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)  * latency). This may be overridden by the IA32_UMWAIT_CONTROL MSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)  * which can force requests for C0.2 to be downgraded to C0.1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static inline void __tpause(u32 ecx, u32 edx, u32 eax)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	/* "tpause %ecx, %edx, %eax;" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	#ifdef CONFIG_AS_TPAUSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	asm volatile("tpause %%ecx\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		     :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		     : "c"(ecx), "d"(edx), "a"(eax));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	#else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	asm volatile(".byte 0x66, 0x0f, 0xae, 0xf1\t\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		     :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		     : "c"(ecx), "d"(edx), "a"(eax));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	#endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #endif /* _ASM_X86_MWAIT_H */