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#define PARAVIRT_HYPERVISOR_TYPE_XEN 1 79 80#ifndef __ASSEMBLY__ 81 82#include <asm/hw_irq.h> 83#include <asm/meminit.h> 84 85/****************************************************************************** 86 * general info 87 */ 88struct pv_info { 89 unsigned int kernel_rpl; 90 int paravirt_enabled; 91 const char *name; 92}; 93 94extern struct pv_info pv_info; 95 96static inline int paravirt_enabled(void) 97{ 98 return pv_info.paravirt_enabled; 99} 100 101static inline unsigned int get_kernel_rpl(void) 102{ 103 return pv_info.kernel_rpl; 104} 105 106/****************************************************************************** 107 * initialization hooks. 108 */ 109struct rsvd_region; 110 111struct pv_init_ops { 112 void (*banner)(void); 113 114 int (*reserve_memory)(struct rsvd_region *region); 115 116 void (*arch_setup_early)(void); 117 void (*arch_setup_console)(char **cmdline_p); 118 int (*arch_setup_nomca)(void); 119 120 void (*post_smp_prepare_boot_cpu)(void); 121 122#ifdef ASM_SUPPORTED 123 unsigned long (*patch_bundle)(void *sbundle, void *ebundle, 124 unsigned long type); 125 unsigned long (*patch_inst)(unsigned long stag, unsigned long etag, 126 unsigned long type); 127#endif 128 void (*patch_branch)(unsigned long tag, unsigned long type); 129}; 130 131extern struct pv_init_ops pv_init_ops; 132 133static inline void paravirt_banner(void) 134{ 135 if (pv_init_ops.banner) 136 pv_init_ops.banner(); 137} 138 139static inline int paravirt_reserve_memory(struct rsvd_region *region) 140{ 141 if (pv_init_ops.reserve_memory) 142 return pv_init_ops.reserve_memory(region); 143 return 0; 144} 145 146static inline void paravirt_arch_setup_early(void) 147{ 148 if (pv_init_ops.arch_setup_early) 149 pv_init_ops.arch_setup_early(); 150} 151 152static inline void paravirt_arch_setup_console(char **cmdline_p) 153{ 154 if (pv_init_ops.arch_setup_console) 155 pv_init_ops.arch_setup_console(cmdline_p); 156} 157 158static inline int paravirt_arch_setup_nomca(void) 159{ 160 if (pv_init_ops.arch_setup_nomca) 161 return pv_init_ops.arch_setup_nomca(); 162 return 0; 163} 164 165static inline void paravirt_post_smp_prepare_boot_cpu(void) 166{ 167 if (pv_init_ops.post_smp_prepare_boot_cpu) 168 pv_init_ops.post_smp_prepare_boot_cpu(); 169} 170 171/****************************************************************************** 172 * replacement of iosapic operations. 173 */ 174 175struct pv_iosapic_ops { 176 void (*pcat_compat_init)(void); 177 178 struct irq_chip *(*__get_irq_chip)(unsigned long trigger); 179 180 unsigned int (*__read)(char __iomem *iosapic, unsigned int reg); 181 void (*__write)(char __iomem *iosapic, unsigned int reg, u32 val); 182}; 183 184extern struct pv_iosapic_ops pv_iosapic_ops; 185 186static inline void 187iosapic_pcat_compat_init(void) 188{ 189 if (pv_iosapic_ops.pcat_compat_init) 190 pv_iosapic_ops.pcat_compat_init(); 191} 192 193static inline struct irq_chip* 194iosapic_get_irq_chip(unsigned long trigger) 195{ 196 return pv_iosapic_ops.__get_irq_chip(trigger); 197} 198 199static inline unsigned int 200__iosapic_read(char __iomem *iosapic, unsigned int reg) 201{ 202 return pv_iosapic_ops.__read(iosapic, reg); 203} 204 205static inline void 206__iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val) 207{ 208 return pv_iosapic_ops.__write(iosapic, reg, val); 209} 210 211/****************************************************************************** 212 * replacement of irq operations. 213 */ 214 215struct pv_irq_ops { 216 void (*register_ipi)(void); 217 218 int (*assign_irq_vector)(int irq); 219 void (*free_irq_vector)(int vector); 220 221 void (*register_percpu_irq)(ia64_vector vec, 222 struct irqaction *action); 223 224 void (*resend_irq)(unsigned int vector); 225}; 226 227extern struct pv_irq_ops pv_irq_ops; 228 229static inline void 230ia64_register_ipi(void) 231{ 232 pv_irq_ops.register_ipi(); 233} 234 235static inline int 236assign_irq_vector(int irq) 237{ 238 return pv_irq_ops.assign_irq_vector(irq); 239} 240 241static inline void 242free_irq_vector(int vector) 243{ 244 return pv_irq_ops.free_irq_vector(vector); 245} 246 247static inline void 248register_percpu_irq(ia64_vector vec, struct irqaction *action) 249{ 250 pv_irq_ops.register_percpu_irq(vec, action); 251} 252 253static inline void 254ia64_resend_irq(unsigned int vector) 255{ 256 pv_irq_ops.resend_irq(vector); 257} 258 259/****************************************************************************** 260 * replacement of time operations. 261 */ 262 263extern struct itc_jitter_data_t itc_jitter_data; 264extern volatile int time_keeper_id; 265 266struct pv_time_ops { 267 void (*init_missing_ticks_accounting)(int cpu); 268 int (*do_steal_accounting)(unsigned long *new_itm); 269 270 void (*clocksource_resume)(void); 271 272 unsigned long long (*sched_clock)(void); 273}; 274 275extern struct pv_time_ops pv_time_ops; 276 277static inline void 278paravirt_init_missing_ticks_accounting(int cpu) 279{ 280 if (pv_time_ops.init_missing_ticks_accounting) 281 pv_time_ops.init_missing_ticks_accounting(cpu); 282} 283 284struct static_key; 285extern struct static_key paravirt_steal_enabled; 286extern struct static_key paravirt_steal_rq_enabled; 287 288static inline int 289paravirt_do_steal_accounting(unsigned long *new_itm) 290{ 291 return pv_time_ops.do_steal_accounting(new_itm); 292} 293 294static inline unsigned long long paravirt_sched_clock(void) 295{ 296 return pv_time_ops.sched_clock(); 297} 298 299#endif /* !__ASSEMBLY__ */ 300 301#else 302/* fallback for native case */ 303 304#ifndef __ASSEMBLY__ 305 306#define paravirt_banner() do { } while (0) 307#define paravirt_reserve_memory(region) 0 308 309#define paravirt_arch_setup_early() do { } while (0) 310#define paravirt_arch_setup_console(cmdline_p) do { } while (0) 311#define paravirt_arch_setup_nomca() 0 312#define paravirt_post_smp_prepare_boot_cpu() do { } while (0) 313 314#define paravirt_init_missing_ticks_accounting(cpu) do { } while (0) 315#define paravirt_do_steal_accounting(new_itm) 0 316 317#endif /* __ASSEMBLY__ */ 318 319 320#endif /* CONFIG_PARAVIRT_GUEST */ 321 322#endif /* __ASM_PARAVIRT_H */ 323