paravirt.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. /******************************************************************************
  2. * arch/ia64/kernel/paravirt.c
  3. *
  4. * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
  5. * VA Linux Systems Japan K.K.
  6. * Yaozu (Eddie) Dong <eddie.dong@intel.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  21. *
  22. */
  23. #include <linux/init.h>
  24. #include <linux/compiler.h>
  25. #include <linux/io.h>
  26. #include <linux/irq.h>
  27. #include <linux/module.h>
  28. #include <linux/types.h>
  29. #include <asm/iosapic.h>
  30. #include <asm/paravirt.h>
  31. /***************************************************************************
  32. * general info
  33. */
  34. struct pv_info pv_info = {
  35. .kernel_rpl = 0,
  36. .paravirt_enabled = 0,
  37. .name = "bare hardware"
  38. };
  39. /***************************************************************************
  40. * pv_cpu_ops
  41. * intrinsics hooks.
  42. */
  43. /* ia64_native_xxx are macros so that we have to make them real functions */
  44. #define DEFINE_VOID_FUNC1(name) \
  45. static void \
  46. ia64_native_ ## name ## _func(unsigned long arg) \
  47. { \
  48. ia64_native_ ## name(arg); \
  49. } \
  50. #define DEFINE_VOID_FUNC2(name) \
  51. static void \
  52. ia64_native_ ## name ## _func(unsigned long arg0, \
  53. unsigned long arg1) \
  54. { \
  55. ia64_native_ ## name(arg0, arg1); \
  56. } \
  57. #define DEFINE_FUNC0(name) \
  58. static unsigned long \
  59. ia64_native_ ## name ## _func(void) \
  60. { \
  61. return ia64_native_ ## name(); \
  62. }
  63. #define DEFINE_FUNC1(name, type) \
  64. static unsigned long \
  65. ia64_native_ ## name ## _func(type arg) \
  66. { \
  67. return ia64_native_ ## name(arg); \
  68. } \
  69. DEFINE_VOID_FUNC1(fc);
  70. DEFINE_VOID_FUNC1(intrin_local_irq_restore);
  71. DEFINE_VOID_FUNC2(ptcga);
  72. DEFINE_VOID_FUNC2(set_rr);
  73. DEFINE_FUNC0(get_psr_i);
  74. DEFINE_FUNC1(thash, unsigned long);
  75. DEFINE_FUNC1(get_cpuid, int);
  76. DEFINE_FUNC1(get_pmd, int);
  77. DEFINE_FUNC1(get_rr, unsigned long);
  78. static void
  79. ia64_native_ssm_i_func(void)
  80. {
  81. ia64_native_ssm(IA64_PSR_I);
  82. }
  83. static void
  84. ia64_native_rsm_i_func(void)
  85. {
  86. ia64_native_rsm(IA64_PSR_I);
  87. }
  88. static void
  89. ia64_native_set_rr0_to_rr4_func(unsigned long val0, unsigned long val1,
  90. unsigned long val2, unsigned long val3,
  91. unsigned long val4)
  92. {
  93. ia64_native_set_rr0_to_rr4(val0, val1, val2, val3, val4);
  94. }
  95. #define CASE_GET_REG(id) \
  96. case _IA64_REG_ ## id: \
  97. res = ia64_native_getreg(_IA64_REG_ ## id); \
  98. break;
  99. #define CASE_GET_AR(id) CASE_GET_REG(AR_ ## id)
  100. #define CASE_GET_CR(id) CASE_GET_REG(CR_ ## id)
  101. unsigned long
  102. ia64_native_getreg_func(int regnum)
  103. {
  104. unsigned long res = -1;
  105. switch (regnum) {
  106. CASE_GET_REG(GP);
  107. CASE_GET_REG(IP);
  108. CASE_GET_REG(PSR);
  109. CASE_GET_REG(TP);
  110. CASE_GET_REG(SP);
  111. CASE_GET_AR(KR0);
  112. CASE_GET_AR(KR1);
  113. CASE_GET_AR(KR2);
  114. CASE_GET_AR(KR3);
  115. CASE_GET_AR(KR4);
  116. CASE_GET_AR(KR5);
  117. CASE_GET_AR(KR6);
  118. CASE_GET_AR(KR7);
  119. CASE_GET_AR(RSC);
  120. CASE_GET_AR(BSP);
  121. CASE_GET_AR(BSPSTORE);
  122. CASE_GET_AR(RNAT);
  123. CASE_GET_AR(FCR);
  124. CASE_GET_AR(EFLAG);
  125. CASE_GET_AR(CSD);
  126. CASE_GET_AR(SSD);
  127. CASE_GET_AR(CFLAG);
  128. CASE_GET_AR(FSR);
  129. CASE_GET_AR(FIR);
  130. CASE_GET_AR(FDR);
  131. CASE_GET_AR(CCV);
  132. CASE_GET_AR(UNAT);
  133. CASE_GET_AR(FPSR);
  134. CASE_GET_AR(ITC);
  135. CASE_GET_AR(PFS);
  136. CASE_GET_AR(LC);
  137. CASE_GET_AR(EC);
  138. CASE_GET_CR(DCR);
  139. CASE_GET_CR(ITM);
  140. CASE_GET_CR(IVA);
  141. CASE_GET_CR(PTA);
  142. CASE_GET_CR(IPSR);
  143. CASE_GET_CR(ISR);
  144. CASE_GET_CR(IIP);
  145. CASE_GET_CR(IFA);
  146. CASE_GET_CR(ITIR);
  147. CASE_GET_CR(IIPA);
  148. CASE_GET_CR(IFS);
  149. CASE_GET_CR(IIM);
  150. CASE_GET_CR(IHA);
  151. CASE_GET_CR(LID);
  152. CASE_GET_CR(IVR);
  153. CASE_GET_CR(TPR);
  154. CASE_GET_CR(EOI);
  155. CASE_GET_CR(IRR0);
  156. CASE_GET_CR(IRR1);
  157. CASE_GET_CR(IRR2);
  158. CASE_GET_CR(IRR3);
  159. CASE_GET_CR(ITV);
  160. CASE_GET_CR(PMV);
  161. CASE_GET_CR(CMCV);
  162. CASE_GET_CR(LRR0);
  163. CASE_GET_CR(LRR1);
  164. default:
  165. printk(KERN_CRIT "wrong_getreg %d\n", regnum);
  166. break;
  167. }
  168. return res;
  169. }
  170. #define CASE_SET_REG(id) \
  171. case _IA64_REG_ ## id: \
  172. ia64_native_setreg(_IA64_REG_ ## id, val); \
  173. break;
  174. #define CASE_SET_AR(id) CASE_SET_REG(AR_ ## id)
  175. #define CASE_SET_CR(id) CASE_SET_REG(CR_ ## id)
  176. void
  177. ia64_native_setreg_func(int regnum, unsigned long val)
  178. {
  179. switch (regnum) {
  180. case _IA64_REG_PSR_L:
  181. ia64_native_setreg(_IA64_REG_PSR_L, val);
  182. ia64_dv_serialize_data();
  183. break;
  184. CASE_SET_REG(SP);
  185. CASE_SET_REG(GP);
  186. CASE_SET_AR(KR0);
  187. CASE_SET_AR(KR1);
  188. CASE_SET_AR(KR2);
  189. CASE_SET_AR(KR3);
  190. CASE_SET_AR(KR4);
  191. CASE_SET_AR(KR5);
  192. CASE_SET_AR(KR6);
  193. CASE_SET_AR(KR7);
  194. CASE_SET_AR(RSC);
  195. CASE_SET_AR(BSP);
  196. CASE_SET_AR(BSPSTORE);
  197. CASE_SET_AR(RNAT);
  198. CASE_SET_AR(FCR);
  199. CASE_SET_AR(EFLAG);
  200. CASE_SET_AR(CSD);
  201. CASE_SET_AR(SSD);
  202. CASE_SET_AR(CFLAG);
  203. CASE_SET_AR(FSR);
  204. CASE_SET_AR(FIR);
  205. CASE_SET_AR(FDR);
  206. CASE_SET_AR(CCV);
  207. CASE_SET_AR(UNAT);
  208. CASE_SET_AR(FPSR);
  209. CASE_SET_AR(ITC);
  210. CASE_SET_AR(PFS);
  211. CASE_SET_AR(LC);
  212. CASE_SET_AR(EC);
  213. CASE_SET_CR(DCR);
  214. CASE_SET_CR(ITM);
  215. CASE_SET_CR(IVA);
  216. CASE_SET_CR(PTA);
  217. CASE_SET_CR(IPSR);
  218. CASE_SET_CR(ISR);
  219. CASE_SET_CR(IIP);
  220. CASE_SET_CR(IFA);
  221. CASE_SET_CR(ITIR);
  222. CASE_SET_CR(IIPA);
  223. CASE_SET_CR(IFS);
  224. CASE_SET_CR(IIM);
  225. CASE_SET_CR(IHA);
  226. CASE_SET_CR(LID);
  227. CASE_SET_CR(IVR);
  228. CASE_SET_CR(TPR);
  229. CASE_SET_CR(EOI);
  230. CASE_SET_CR(IRR0);
  231. CASE_SET_CR(IRR1);
  232. CASE_SET_CR(IRR2);
  233. CASE_SET_CR(IRR3);
  234. CASE_SET_CR(ITV);
  235. CASE_SET_CR(PMV);
  236. CASE_SET_CR(CMCV);
  237. CASE_SET_CR(LRR0);
  238. CASE_SET_CR(LRR1);
  239. default:
  240. printk(KERN_CRIT "wrong setreg %d\n", regnum);
  241. break;
  242. }
  243. }
  244. struct pv_cpu_ops pv_cpu_ops = {
  245. .fc = ia64_native_fc_func,
  246. .thash = ia64_native_thash_func,
  247. .get_cpuid = ia64_native_get_cpuid_func,
  248. .get_pmd = ia64_native_get_pmd_func,
  249. .ptcga = ia64_native_ptcga_func,
  250. .get_rr = ia64_native_get_rr_func,
  251. .set_rr = ia64_native_set_rr_func,
  252. .set_rr0_to_rr4 = ia64_native_set_rr0_to_rr4_func,
  253. .ssm_i = ia64_native_ssm_i_func,
  254. .getreg = ia64_native_getreg_func,
  255. .setreg = ia64_native_setreg_func,
  256. .rsm_i = ia64_native_rsm_i_func,
  257. .get_psr_i = ia64_native_get_psr_i_func,
  258. .intrin_local_irq_restore
  259. = ia64_native_intrin_local_irq_restore_func,
  260. };
  261. EXPORT_SYMBOL(pv_cpu_ops);
  262. /******************************************************************************
  263. * replacement of hand written assembly codes.
  264. */
  265. void
  266. paravirt_cpu_asm_init(const struct pv_cpu_asm_switch *cpu_asm_switch)
  267. {
  268. extern unsigned long paravirt_switch_to_targ;
  269. extern unsigned long paravirt_leave_syscall_targ;
  270. extern unsigned long paravirt_work_processed_syscall_targ;
  271. extern unsigned long paravirt_leave_kernel_targ;
  272. paravirt_switch_to_targ = cpu_asm_switch->switch_to;
  273. paravirt_leave_syscall_targ = cpu_asm_switch->leave_syscall;
  274. paravirt_work_processed_syscall_targ =
  275. cpu_asm_switch->work_processed_syscall;
  276. paravirt_leave_kernel_targ = cpu_asm_switch->leave_kernel;
  277. }