hc
2024-11-01 2f529f9b558ca1c1bd74be7437a84e4711743404
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
 * SPDX-License-Identifier: GPL-2.0
 *
 * Copyright (C) 2018 Philippe Gerum  <rpm@xenomai.org>.
 */
#ifndef _ASM_ARM64_IRQ_PIPELINE_H
#define _ASM_ARM64_IRQ_PIPELINE_H
 
#include <asm-generic/irq_pipeline.h>
 
#ifdef CONFIG_IRQ_PIPELINE
 
/*
 * In order to cope with the limited number of SGIs available to us,
 * In-band IPI messages are multiplexed over SGI0, whereas out-of-band
 * IPIs are directly mapped to SGI1-2.
 */
#define OOB_NR_IPI        2
#define OOB_IPI_OFFSET        1 /* SGI1 */
#define TIMER_OOB_IPI        (ipi_irq_base + OOB_IPI_OFFSET)
#define RESCHEDULE_OOB_IPI    (TIMER_OOB_IPI + 1)
 
extern int ipi_irq_base;
 
static inline notrace
unsigned long arch_irqs_virtual_to_native_flags(int stalled)
{
   return (!!stalled) << IRQMASK_I_POS;
}
 
static inline notrace
unsigned long arch_irqs_native_to_virtual_flags(unsigned long flags)
{
   return (!!hard_irqs_disabled_flags(flags)) << IRQMASK_i_POS;
}
 
static inline notrace unsigned long arch_local_irq_save(void)
{
   int stalled = inband_irq_save();
   barrier();
   return arch_irqs_virtual_to_native_flags(stalled);
}
 
static inline notrace void arch_local_irq_enable(void)
{
   barrier();
   inband_irq_enable();
}
 
static inline notrace void arch_local_irq_disable(void)
{
   inband_irq_disable();
   barrier();
}
 
static inline notrace unsigned long arch_local_save_flags(void)
{
   int stalled = inband_irqs_disabled();
   barrier();
   return arch_irqs_virtual_to_native_flags(stalled);
}
 
static inline int arch_irqs_disabled_flags(unsigned long flags)
{
   return native_irqs_disabled_flags(flags);
}
 
static inline notrace void arch_local_irq_restore(unsigned long flags)
{
   inband_irq_restore(arch_irqs_disabled_flags(flags));
   barrier();
}
 
static inline
void arch_save_timer_regs(struct pt_regs *dst, struct pt_regs *src)
{
   dst->pstate = src->pstate;
   dst->pc = src->pc;
}
 
static inline bool arch_steal_pipelined_tick(struct pt_regs *regs)
{
   return !!(regs->pstate & IRQMASK_I_BIT);
}
 
static inline int arch_enable_oob_stage(void)
{
   return 0;
}
 
/*
 * We use neither the generic entry code nor
 * kentry_enter/exit_pipelined yet. We still build a no-op version of
 * the latter for now, until we enventually switch to using whichever
 * of them is available first.
 */
#define arch_kentry_get_irqstate(__regs)    0
 
#define arch_kentry_set_irqstate(__regs, __irqstate)    \
   do { (void)__irqstate; } while (0)
 
#else  /* !CONFIG_IRQ_PIPELINE */
 
static inline unsigned long arch_local_irq_save(void)
{
   return native_irq_save();
}
 
static inline void arch_local_irq_enable(void)
{
   native_irq_enable();
}
 
static inline void arch_local_irq_disable(void)
{
   native_irq_disable();
}
 
static inline unsigned long arch_local_save_flags(void)
{
   return native_save_flags();
}
 
static inline void arch_local_irq_restore(unsigned long flags)
{
   native_irq_restore(flags);
}
 
static inline int arch_irqs_disabled_flags(unsigned long flags)
{
   return native_irqs_disabled_flags(flags);
}
 
#endif /* !CONFIG_IRQ_PIPELINE */
 
static inline int arch_irqs_disabled(void)
{
   return arch_irqs_disabled_flags(arch_local_save_flags());
}
 
#endif /* _ASM_ARM64_IRQ_PIPELINE_H */