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