1/******************************************************************************
2 * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
3 *                    VA Linux Systems Japan K.K.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 *
19 */
20
21
22#ifndef __ASM_PARAVIRT_H
23#define __ASM_PARAVIRT_H
24
25#ifndef __ASSEMBLY__
26/******************************************************************************
27 * fsys related addresses
28 */
29struct pv_fsys_data {
30	unsigned long *fsyscall_table;
31	void *fsys_bubble_down;
32};
33
34extern struct pv_fsys_data pv_fsys_data;
35
36unsigned long *paravirt_get_fsyscall_table(void);
37char *paravirt_get_fsys_bubble_down(void);
38
39/******************************************************************************
40 * patchlist addresses for gate page
41 */
42enum pv_gate_patchlist {
43	PV_GATE_START_FSYSCALL,
44	PV_GATE_END_FSYSCALL,
45
46	PV_GATE_START_BRL_FSYS_BUBBLE_DOWN,
47	PV_GATE_END_BRL_FSYS_BUBBLE_DOWN,
48
49	PV_GATE_START_VTOP,
50	PV_GATE_END_VTOP,
51
52	PV_GATE_START_MCKINLEY_E9,
53	PV_GATE_END_MCKINLEY_E9,
54};
55
56struct pv_patchdata {
57	unsigned long start_fsyscall_patchlist;
58	unsigned long end_fsyscall_patchlist;
59	unsigned long start_brl_fsys_bubble_down_patchlist;
60	unsigned long end_brl_fsys_bubble_down_patchlist;
61	unsigned long start_vtop_patchlist;
62	unsigned long end_vtop_patchlist;
63	unsigned long start_mckinley_e9_patchlist;
64	unsigned long end_mckinley_e9_patchlist;
65
66	void *gate_section;
67};
68
69extern struct pv_patchdata pv_patchdata;
70
71unsigned long paravirt_get_gate_patchlist(enum pv_gate_patchlist type);
72void *paravirt_get_gate_section(void);
73#endif
74
75#ifdef CONFIG_PARAVIRT_GUEST
76
77#define PARAVIRT_HYPERVISOR_TYPE_DEFAULT	0
78
79#ifndef __ASSEMBLY__
80
81#include <asm/hw_irq.h>
82#include <asm/meminit.h>
83
84/******************************************************************************
85 * general info
86 */
87struct pv_info {
88	unsigned int kernel_rpl;
89	int paravirt_enabled;
90	const char *name;
91};
92
93extern struct pv_info pv_info;
94
95static inline int paravirt_enabled(void)
96{
97	return pv_info.paravirt_enabled;
98}
99
100static inline unsigned int get_kernel_rpl(void)
101{
102	return pv_info.kernel_rpl;
103}
104
105/******************************************************************************
106 * initialization hooks.
107 */
108struct rsvd_region;
109
110struct pv_init_ops {
111	void (*banner)(void);
112
113	int (*reserve_memory)(struct rsvd_region *region);
114
115	void (*arch_setup_early)(void);
116	void (*arch_setup_console)(char **cmdline_p);
117	int (*arch_setup_nomca)(void);
118
119	void (*post_smp_prepare_boot_cpu)(void);
120
121#ifdef ASM_SUPPORTED
122	unsigned long (*patch_bundle)(void *sbundle, void *ebundle,
123				      unsigned long type);
124	unsigned long (*patch_inst)(unsigned long stag, unsigned long etag,
125				    unsigned long type);
126#endif
127	void (*patch_branch)(unsigned long tag, unsigned long type);
128};
129
130extern struct pv_init_ops pv_init_ops;
131
132static inline void paravirt_banner(void)
133{
134	if (pv_init_ops.banner)
135		pv_init_ops.banner();
136}
137
138static inline int paravirt_reserve_memory(struct rsvd_region *region)
139{
140	if (pv_init_ops.reserve_memory)
141		return pv_init_ops.reserve_memory(region);
142	return 0;
143}
144
145static inline void paravirt_arch_setup_early(void)
146{
147	if (pv_init_ops.arch_setup_early)
148		pv_init_ops.arch_setup_early();
149}
150
151static inline void paravirt_arch_setup_console(char **cmdline_p)
152{
153	if (pv_init_ops.arch_setup_console)
154		pv_init_ops.arch_setup_console(cmdline_p);
155}
156
157static inline int paravirt_arch_setup_nomca(void)
158{
159	if (pv_init_ops.arch_setup_nomca)
160		return pv_init_ops.arch_setup_nomca();
161	return 0;
162}
163
164static inline void paravirt_post_smp_prepare_boot_cpu(void)
165{
166	if (pv_init_ops.post_smp_prepare_boot_cpu)
167		pv_init_ops.post_smp_prepare_boot_cpu();
168}
169
170/******************************************************************************
171 * replacement of iosapic operations.
172 */
173
174struct pv_iosapic_ops {
175	void (*pcat_compat_init)(void);
176
177	struct irq_chip *(*__get_irq_chip)(unsigned long trigger);
178
179	unsigned int (*__read)(char __iomem *iosapic, unsigned int reg);
180	void (*__write)(char __iomem *iosapic, unsigned int reg, u32 val);
181};
182
183extern struct pv_iosapic_ops pv_iosapic_ops;
184
185static inline void
186iosapic_pcat_compat_init(void)
187{
188	if (pv_iosapic_ops.pcat_compat_init)
189		pv_iosapic_ops.pcat_compat_init();
190}
191
192static inline struct irq_chip*
193iosapic_get_irq_chip(unsigned long trigger)
194{
195	return pv_iosapic_ops.__get_irq_chip(trigger);
196}
197
198static inline unsigned int
199__iosapic_read(char __iomem *iosapic, unsigned int reg)
200{
201	return pv_iosapic_ops.__read(iosapic, reg);
202}
203
204static inline void
205__iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
206{
207	return pv_iosapic_ops.__write(iosapic, reg, val);
208}
209
210/******************************************************************************
211 * replacement of irq operations.
212 */
213
214struct pv_irq_ops {
215	void (*register_ipi)(void);
216
217	int (*assign_irq_vector)(int irq);
218	void (*free_irq_vector)(int vector);
219
220	void (*register_percpu_irq)(ia64_vector vec,
221				    struct irqaction *action);
222
223	void (*resend_irq)(unsigned int vector);
224};
225
226extern struct pv_irq_ops pv_irq_ops;
227
228static inline void
229ia64_register_ipi(void)
230{
231	pv_irq_ops.register_ipi();
232}
233
234static inline int
235assign_irq_vector(int irq)
236{
237	return pv_irq_ops.assign_irq_vector(irq);
238}
239
240static inline void
241free_irq_vector(int vector)
242{
243	return pv_irq_ops.free_irq_vector(vector);
244}
245
246static inline void
247register_percpu_irq(ia64_vector vec, struct irqaction *action)
248{
249	pv_irq_ops.register_percpu_irq(vec, action);
250}
251
252static inline void
253ia64_resend_irq(unsigned int vector)
254{
255	pv_irq_ops.resend_irq(vector);
256}
257
258/******************************************************************************
259 * replacement of time operations.
260 */
261
262extern struct itc_jitter_data_t itc_jitter_data;
263extern volatile int time_keeper_id;
264
265struct pv_time_ops {
266	void (*init_missing_ticks_accounting)(int cpu);
267	int (*do_steal_accounting)(unsigned long *new_itm);
268
269	void (*clocksource_resume)(void);
270
271	unsigned long long (*sched_clock)(void);
272};
273
274extern struct pv_time_ops pv_time_ops;
275
276static inline void
277paravirt_init_missing_ticks_accounting(int cpu)
278{
279	if (pv_time_ops.init_missing_ticks_accounting)
280		pv_time_ops.init_missing_ticks_accounting(cpu);
281}
282
283struct static_key;
284extern struct static_key paravirt_steal_enabled;
285extern struct static_key paravirt_steal_rq_enabled;
286
287static inline int
288paravirt_do_steal_accounting(unsigned long *new_itm)
289{
290	return pv_time_ops.do_steal_accounting(new_itm);
291}
292
293static inline unsigned long long paravirt_sched_clock(void)
294{
295	return pv_time_ops.sched_clock();
296}
297
298#endif /* !__ASSEMBLY__ */
299
300#else
301/* fallback for native case */
302
303#ifndef __ASSEMBLY__
304
305#define paravirt_banner()				do { } while (0)
306#define paravirt_reserve_memory(region)			0
307
308#define paravirt_arch_setup_early()			do { } while (0)
309#define paravirt_arch_setup_console(cmdline_p)		do { } while (0)
310#define paravirt_arch_setup_nomca()			0
311#define paravirt_post_smp_prepare_boot_cpu()		do { } while (0)
312
313#define paravirt_init_missing_ticks_accounting(cpu)	do { } while (0)
314#define paravirt_do_steal_accounting(new_itm)		0
315
316#endif /* __ASSEMBLY__ */
317
318
319#endif /* CONFIG_PARAVIRT_GUEST */
320
321#endif /* __ASM_PARAVIRT_H */
322