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-or-later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright 2009 Freescale Semiconductor, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * provides masks and opcode images for use by code generation, emulation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * and for instructions that older assemblers might not know about
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #ifndef _ASM_POWERPC_DBELL_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #define _ASM_POWERPC_DBELL_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/threads.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <asm/cputhreads.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <asm/ppc-opcode.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <asm/feature-fixups.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <asm/kvm_ppc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #define PPC_DBELL_MSG_BRDCAST	(0x04000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #define PPC_DBELL_TYPE(x)	(((x) & 0xf) << (63-36))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define PPC_DBELL_TYPE_MASK	PPC_DBELL_TYPE(0xf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define PPC_DBELL_LPID(x)	((x) << (63 - 49))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define PPC_DBELL_PIR_MASK	0x3fff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) enum ppc_dbell {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	PPC_DBELL = 0,		/* doorbell */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	PPC_DBELL_CRIT = 1,	/* critical doorbell */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	PPC_G_DBELL = 2,	/* guest doorbell */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	PPC_G_DBELL_CRIT = 3,	/* guest critical doorbell */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	PPC_G_DBELL_MC = 4,	/* guest mcheck doorbell */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	PPC_DBELL_SERVER = 5,	/* doorbell on server */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #ifdef CONFIG_PPC_BOOK3S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define PPC_DBELL_MSGTYPE		PPC_DBELL_SERVER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) static inline void _ppc_msgsnd(u32 msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	__asm__ __volatile__ (ASM_FTR_IFSET(PPC_MSGSND(%1), PPC_MSGSNDP(%1), %0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 				: : "i" (CPU_FTR_HVMODE), "r" (msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) /* sync before sending message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) static inline void ppc_msgsnd_sync(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	__asm__ __volatile__ ("sync" : : : "memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) /* sync after taking message interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) static inline void ppc_msgsync(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	/* sync is not required when taking messages from the same core */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	__asm__ __volatile__ (ASM_FTR_IFSET(PPC_MSGSYNC " ; lwsync", "", %0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 				: : "i" (CPU_FTR_HVMODE|CPU_FTR_ARCH_300));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) static inline void _ppc_msgclr(u32 msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	__asm__ __volatile__ (ASM_FTR_IFSET(PPC_MSGCLR(%1), PPC_MSGCLRP(%1), %0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 				: : "i" (CPU_FTR_HVMODE), "r" (msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) static inline void ppc_msgclr(enum ppc_dbell type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	u32 msg = PPC_DBELL_TYPE(type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	_ppc_msgclr(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) #else /* CONFIG_PPC_BOOK3S */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) #define PPC_DBELL_MSGTYPE		PPC_DBELL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) static inline void _ppc_msgsnd(u32 msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	__asm__ __volatile__ (PPC_MSGSND(%0) : : "r" (msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) /* sync before sending message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) static inline void ppc_msgsnd_sync(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	__asm__ __volatile__ ("sync" : : : "memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) /* sync after taking message interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) static inline void ppc_msgsync(void)
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) #endif /* CONFIG_PPC_BOOK3S */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) extern void doorbell_exception(struct pt_regs *regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) static inline void ppc_msgsnd(enum ppc_dbell type, u32 flags, u32 tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	u32 msg = PPC_DBELL_TYPE(type) | (flags & PPC_DBELL_MSG_BRDCAST) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 			(tag & 0x07ffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	_ppc_msgsnd(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)  * Doorbells must only be used if CPU_FTR_DBELL is available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)  * msgsnd is used in HV, and msgsndp is used in !HV.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)  * These should be used by platform code that is aware of restrictions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)  * Other arch code should use ->cause_ipi.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)  * doorbell_global_ipi() sends a dbell to any target CPU.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)  * Must be used only by architectures that address msgsnd target
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)  * by PIR/get_hard_smp_processor_id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static inline void doorbell_global_ipi(int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	u32 tag = get_hard_smp_processor_id(cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	kvmppc_set_host_ipi(cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	/* Order previous accesses vs. msgsnd, which is treated as a store */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	ppc_msgsnd_sync();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	ppc_msgsnd(PPC_DBELL_MSGTYPE, 0, tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)  * doorbell_core_ipi() sends a dbell to a target CPU in the same core.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)  * Must be used only by architectures that address msgsnd target
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)  * by TIR/cpu_thread_in_core.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static inline void doorbell_core_ipi(int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	u32 tag = cpu_thread_in_core(cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	kvmppc_set_host_ipi(cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	/* Order previous accesses vs. msgsnd, which is treated as a store */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	ppc_msgsnd_sync();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	ppc_msgsnd(PPC_DBELL_MSGTYPE, 0, tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)  * Attempt to cause a core doorbell if destination is on the same core.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)  * Returns 1 on success, 0 on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static inline int doorbell_try_core_ipi(int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	int this_cpu = get_cpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	if (cpumask_test_cpu(cpu, cpu_sibling_mask(this_cpu))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		doorbell_core_ipi(cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	put_cpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #endif /* CONFIG_SMP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #endif /* _ASM_POWERPC_DBELL_H */