18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * IRQ flags handling
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci#ifndef _ASM_IRQFLAGS_H
68c2ecf20Sopenharmony_ci#define _ASM_IRQFLAGS_H
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__
98c2ecf20Sopenharmony_ci/*
108c2ecf20Sopenharmony_ci * Get definitions for arch_local_save_flags(x), etc.
118c2ecf20Sopenharmony_ci */
128c2ecf20Sopenharmony_ci#include <asm/hw_irq.h>
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#else
158c2ecf20Sopenharmony_ci#ifdef CONFIG_TRACE_IRQFLAGS
168c2ecf20Sopenharmony_ci#ifdef CONFIG_IRQSOFF_TRACER
178c2ecf20Sopenharmony_ci/*
188c2ecf20Sopenharmony_ci * Since the ftrace irqsoff latency trace checks CALLER_ADDR1,
198c2ecf20Sopenharmony_ci * which is the stack frame here, we need to force a stack frame
208c2ecf20Sopenharmony_ci * in case we came from user space.
218c2ecf20Sopenharmony_ci */
228c2ecf20Sopenharmony_ci#define TRACE_WITH_FRAME_BUFFER(func)		\
238c2ecf20Sopenharmony_ci	mflr	r0;				\
248c2ecf20Sopenharmony_ci	stdu	r1, -STACK_FRAME_OVERHEAD(r1);	\
258c2ecf20Sopenharmony_ci	std	r0, 16(r1);			\
268c2ecf20Sopenharmony_ci	stdu	r1, -STACK_FRAME_OVERHEAD(r1);	\
278c2ecf20Sopenharmony_ci	bl func;				\
288c2ecf20Sopenharmony_ci	ld	r1, 0(r1);			\
298c2ecf20Sopenharmony_ci	ld	r1, 0(r1);
308c2ecf20Sopenharmony_ci#else
318c2ecf20Sopenharmony_ci#define TRACE_WITH_FRAME_BUFFER(func)		\
328c2ecf20Sopenharmony_ci	bl func;
338c2ecf20Sopenharmony_ci#endif
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci/*
368c2ecf20Sopenharmony_ci * These are calls to C code, so the caller must be prepared for volatiles to
378c2ecf20Sopenharmony_ci * be clobbered.
388c2ecf20Sopenharmony_ci */
398c2ecf20Sopenharmony_ci#define TRACE_ENABLE_INTS	TRACE_WITH_FRAME_BUFFER(trace_hardirqs_on)
408c2ecf20Sopenharmony_ci#define TRACE_DISABLE_INTS	TRACE_WITH_FRAME_BUFFER(trace_hardirqs_off)
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci/*
438c2ecf20Sopenharmony_ci * This is used by assembly code to soft-disable interrupts first and
448c2ecf20Sopenharmony_ci * reconcile irq state.
458c2ecf20Sopenharmony_ci *
468c2ecf20Sopenharmony_ci * NB: This may call C code, so the caller must be prepared for volatiles to
478c2ecf20Sopenharmony_ci * be clobbered.
488c2ecf20Sopenharmony_ci */
498c2ecf20Sopenharmony_ci#define RECONCILE_IRQ_STATE(__rA, __rB)		\
508c2ecf20Sopenharmony_ci	lbz	__rA,PACAIRQSOFTMASK(r13);	\
518c2ecf20Sopenharmony_ci	lbz	__rB,PACAIRQHAPPENED(r13);	\
528c2ecf20Sopenharmony_ci	andi.	__rA,__rA,IRQS_DISABLED;	\
538c2ecf20Sopenharmony_ci	li	__rA,IRQS_DISABLED;		\
548c2ecf20Sopenharmony_ci	ori	__rB,__rB,PACA_IRQ_HARD_DIS;	\
558c2ecf20Sopenharmony_ci	stb	__rB,PACAIRQHAPPENED(r13);	\
568c2ecf20Sopenharmony_ci	bne	44f;				\
578c2ecf20Sopenharmony_ci	stb	__rA,PACAIRQSOFTMASK(r13);	\
588c2ecf20Sopenharmony_ci	TRACE_DISABLE_INTS;			\
598c2ecf20Sopenharmony_ci44:
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci#else
628c2ecf20Sopenharmony_ci#define TRACE_ENABLE_INTS
638c2ecf20Sopenharmony_ci#define TRACE_DISABLE_INTS
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci#define RECONCILE_IRQ_STATE(__rA, __rB)		\
668c2ecf20Sopenharmony_ci	lbz	__rA,PACAIRQHAPPENED(r13);	\
678c2ecf20Sopenharmony_ci	li	__rB,IRQS_DISABLED;		\
688c2ecf20Sopenharmony_ci	ori	__rA,__rA,PACA_IRQ_HARD_DIS;	\
698c2ecf20Sopenharmony_ci	stb	__rB,PACAIRQSOFTMASK(r13);	\
708c2ecf20Sopenharmony_ci	stb	__rA,PACAIRQHAPPENED(r13)
718c2ecf20Sopenharmony_ci#endif
728c2ecf20Sopenharmony_ci#endif
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci#endif
75