25 #include <linux/kernel.h>
29 #include <asm/xen/hypervisor.h>
41 .paravirt_enabled = 1,
45 #define IA64_RSC_PL_SHIFT 2
46 #define IA64_RSC_PL_BIT_SIZE 2
47 #define IA64_RSC_PL_MASK \
48 (((1UL << IA64_RSC_PL_BIT_SIZE) - 1) << IA64_RSC_PL_SHIFT)
57 xen_info.kernel_rpl = rpl;
82 xen_panic_event,
NULL, 0
85 static void xen_pm_power_off(
void)
95 "Running on Xen! pl = %d start_info_pfn=0x%lx nr_pages=%ld "
112 xen_arch_setup_early(
void)
133 xen_arch_setup_console(
char **cmdline_p)
140 #if !defined(CONFIG_VT) || !defined(CONFIG_DUMMY_CONSOLE)
146 xen_arch_setup_nomca(
void)
152 xen_post_smp_prepare_boot_cpu(
void)
159 xen_patch_bundle(
void *sbundle,
void *ebundle,
unsigned long type);
162 xen_patch_branch(
unsigned long tag,
unsigned long type);
165 .banner = xen_banner,
167 .reserve_memory = xen_reserve_memory,
169 .arch_setup_early = xen_arch_setup_early,
170 .arch_setup_console = xen_arch_setup_console,
171 .arch_setup_nomca = xen_arch_setup_nomca,
173 .post_smp_prepare_boot_cpu = xen_post_smp_prepare_boot_cpu,
175 .patch_bundle = xen_patch_bundle,
177 .patch_branch = xen_patch_branch,
188 .fsyscall_table = (
unsigned long *)xen_fsyscall_table,
197 #define DECLARE(name) \
198 extern unsigned long __xen_start_gate_##name##_patchlist[]; \
199 extern unsigned long __xen_end_gate_##name##_patchlist[]
208 #define ASSIGN(name) \
209 .start_##name##_patchlist = \
210 (unsigned long)__xen_start_gate_##name##_patchlist, \
211 .end_##name##_patchlist = \
212 (unsigned long)__xen_end_gate_##name##_patchlist
216 ASSIGN(brl_fsys_bubble_down),
220 .gate_section = (
void*)__xen_start_gate_section,
228 #ifndef ASM_SUPPORTED
230 xen_set_itm_with_offset(
unsigned long val)
238 xen_get_itm_with_offset(
void)
253 xen_set_itc(
unsigned long val)
267 unsigned long itc_offset;
268 unsigned long itc_last;
269 unsigned long ret_itc_last;
280 }
while (
unlikely(ret_itc_last != itc_last));
298 static void xen_setreg(
int regnum,
unsigned long val)
311 xen_set_itm_with_offset(val);
322 static unsigned long xen_getreg(
int regnum)
334 res = xen_get_itm_with_offset();
379 xen_intrin_local_irq_restore(
unsigned long mask)
387 #define __DEFINE_FUNC(name, code) \
388 extern const char xen_ ## name ## _direct_start[]; \
389 extern const char xen_ ## name ## _direct_end[]; \
391 ".proc xen_" #name "\n" \
393 "xen_" #name "_direct_start:\n" \
395 "xen_" #name "_direct_end:\n" \
396 "br.cond.sptk.many b6\n" \
397 ".endp xen_" #name "\n")
399 #define DEFINE_VOID_FUNC0(name, code) \
401 xen_ ## name (void); \
402 __DEFINE_FUNC(name, code)
404 #define DEFINE_VOID_FUNC1(name, code) \
406 xen_ ## name (unsigned long arg); \
407 __DEFINE_FUNC(name, code)
409 #define DEFINE_VOID_FUNC1_VOID(name, code) \
411 xen_ ## name (void *arg); \
412 __DEFINE_FUNC(name, code)
414 #define DEFINE_VOID_FUNC2(name, code) \
416 xen_ ## name (unsigned long arg0, \
417 unsigned long arg1); \
418 __DEFINE_FUNC(name, code)
420 #define DEFINE_FUNC0(name, code) \
421 extern unsigned long \
422 xen_ ## name (void); \
423 __DEFINE_FUNC(name, code)
425 #define DEFINE_FUNC1(name, type, code) \
426 extern unsigned long \
427 xen_ ## name (type arg); \
428 __DEFINE_FUNC(name, code)
430 #define XEN_PSR_I_ADDR_ADDR (XSI_BASE + XSI_PSR_I_ADDR_OFS)
458 "add r8 = r8, r2\n");
506 "ld8 r9 = [r2], " __stringify(XSI_ITC_LAST_OFS)
" - "
516 "cmp.gtu p6, p0 = r3, r8\n"
518 "(p6) add r8 = 1, r3\n"
522 "cmpxchg8.acq r10 = [r2], r8, ar.ccv\n"
524 "cmp.ne p6, p0 = r10, r3\n"
526 "(p6) br.cond.spnt 888b\n");
556 "cmp.ne p6, p7 = r8, r0\n"
564 "(p6) ld1.acq r10 = [r9]\n"
568 "(p6) cmp.ne.unc p8, p0 = r10, r0\n"
574 "(p7) st1.rel [r9] = r11\n"
581 "(p8) st1.rel [r9] = r0, -1\n"
584 "(p8) ld1.acq r11 = [r9]\n"
587 "(p8) cmp.ne.unc p9, p10 = r11, r0\n"
611 "ld1.acq r9 = [r9]\n"
613 "cmp.eq.unc p6, p0 = r9, r0\n"
643 DEFINE_VOID_FUNC0(ssm_i,
648 "ld1.acq r9 = [r8]\n"
650 "st1.rel [r8] = r0, -1\n"
654 "cmp.eq.unc p0, p6 = r9, r0\n"
659 "(p6) ld1.acq r8 = [r8]\n"
661 "(p6) cmp.eq.unc p6, p7 = r8, r0\n"
674 DEFINE_VOID_FUNC0(rsm_i,
681 "st1.rel [r8] = r9\n");
685 unsigned long val2,
unsigned long val3,
687 __DEFINE_FUNC(set_rr0_to_rr4,
691 extern unsigned long xen_getreg(
int regnum);
692 #define __DEFINE_GET_REG(id, privop) \
693 "mov r2 = " __stringify(_IA64_REG_ ## id) "\n" \
695 "cmp.eq p6, p0 = r2, r8\n" \
697 "(p6) break " __stringify(HYPERPRIVOP_GET_ ## privop) "\n" \
698 "(p6) br.cond.sptk.many b6\n" \
702 __DEFINE_GET_REG(
PSR,
PSR)
707 "cmp.eq p6, p0 = r2, r8\n"
709 "(p6) br.cond.spnt xen_get_itc\n"
715 "cmp.eq p6, p0 = r2, r8\n"
717 "(p6) br.cond.spnt xen_get_itm_with_offset\n"
720 __DEFINE_GET_REG(CR_IVR,
IVR)
721 __DEFINE_GET_REG(CR_TPR,
TPR)
724 "movl r2 = ia64_native_getreg_func\n"
728 "br.cond.sptk.many b7\n");
730 extern void xen_setreg(
int regnum,
unsigned long val);
731 #define __DEFINE_SET_REG(id, privop) \
732 "mov r2 = " __stringify(_IA64_REG_ ## id) "\n" \
734 "cmp.eq p6, p0 = r2, r9\n" \
736 "(p6) break " __stringify(HYPERPRIVOP_ ## privop) "\n" \
737 "(p6) br.cond.sptk.many b6\n" \
753 "cmp.ge p6, p0 = r9, r2\n"
754 "sub r17 = r17, r2\n"
756 "(p6) cmp.ge.unc p7, p0 = "
762 "(p7) mov r8 = r17\n"
768 "cmp.eq p6, p0 = r2, r8\n"
770 "(p6) br.cond.spnt xen_set_itm_with_offset\n"
775 "cmp.eq p6, p0 = r2, r8\n"
777 "(p6) br.cond.spnt xen_set_itc\n"
779 __DEFINE_SET_REG(CR_TPR, SET_TPR)
780 __DEFINE_SET_REG(CR_EOI,
EOI)
783 "movl r2 = ia64_native_setreg_func\n"
787 "br.cond.sptk.many b7\n");
790 static const struct pv_cpu_ops xen_cpu_ops __initconst = {
795 .getreg = xen_getreg,
796 .setreg = xen_setreg,
803 .get_psr_i = xen_get_psr_i,
804 .intrin_local_irq_restore
805 = xen_intrin_local_irq_restore,
818 .switch_to = (
unsigned long)&xen_switch_to,
819 .leave_syscall = (
unsigned long)&xen_leave_syscall,
820 .work_processed_syscall = (
unsigned long)&xen_work_processed_syscall,
821 .leave_kernel = (
unsigned long)&xen_leave_kernel,
829 xen_pcat_compat_init(
void)
835 xen_iosapic_get_irq_chip(
unsigned long trigger)
841 xen_iosapic_read(
char __iomem *iosapic,
unsigned int reg)
846 apic_op.apic_physbase = (
unsigned long)iosapic -
852 return apic_op.value;
856 xen_iosapic_write(
char __iomem *iosapic,
unsigned int reg,
u32 val)
868 .pcat_compat_init = xen_pcat_compat_init,
869 .__get_irq_chip = xen_iosapic_get_irq_chip,
871 .__read = xen_iosapic_read,
872 .__write = xen_iosapic_write,
901 #define DEFINE_FUNC_GETREG(name, privop) \
902 DEFINE_FUNC0(get_ ## name, \
903 "break "__stringify(HYPERPRIVOP_GET_ ## privop) "\n")
905 DEFINE_FUNC_GETREG(
psr,
PSR);
906 DEFINE_FUNC_GETREG(eflag, EFLAG);
907 DEFINE_FUNC_GETREG(ivr,
IVR);
908 DEFINE_FUNC_GETREG(
tpr,
TPR);
910 #define DEFINE_FUNC_SET_KR(n) \
911 DEFINE_VOID_FUNC0(set_kr ## n, \
914 "mov r8 = " #n "\n" \
915 "break " __stringify(HYPERPRIVOP_SET_KR) "\n")
917 DEFINE_FUNC_SET_KR(0);
918 DEFINE_FUNC_SET_KR(1);
919 DEFINE_FUNC_SET_KR(2);
920 DEFINE_FUNC_SET_KR(3);
921 DEFINE_FUNC_SET_KR(4);
922 DEFINE_FUNC_SET_KR(5);
923 DEFINE_FUNC_SET_KR(6);
924 DEFINE_FUNC_SET_KR(7);
926 #define __DEFINE_FUNC_SETREG(name, privop) \
927 DEFINE_VOID_FUNC0(name, \
928 "break "__stringify(HYPERPRIVOP_ ## privop) "\n")
930 #define DEFINE_FUNC_SETREG(name, privop) \
931 __DEFINE_FUNC_SETREG(set_ ## name, SET_ ## privop)
933 DEFINE_FUNC_SETREG(eflag, EFLAG);
934 DEFINE_FUNC_SETREG(
tpr,
TPR);
935 __DEFINE_FUNC_SETREG(
eoi,
EOI);
937 extern const char xen_check_events[];
938 extern const char __xen_intrin_local_irq_restore_direct_start[];
939 extern const char __xen_intrin_local_irq_restore_direct_end[];
940 extern const unsigned long __xen_intrin_local_irq_restore_direct_reloc;
944 ".proc xen_check_events\n"
945 "xen_check_events:\n"
950 "st1.rel [r9] = r0, -1\n"
953 "ld1.acq r11 = [r9]\n"
956 "cmp.ne p9, p10 = r11, r0\n"
961 "br.cond.sptk.many b6\n"
962 ".endp xen_check_events\n"
965 ".proc __xen_intrin_local_irq_restore_direct\n"
966 "__xen_intrin_local_irq_restore_direct:\n"
967 "__xen_intrin_local_irq_restore_direct_start:\n"
970 "cmp.ne p6, p7 = r8, r0\n"
980 "(p6) ld1.acq r10 = [r9]\n"
981 "adds r17 = 1f - 1b, r17\n"
986 "(p6) cmp.ne.unc p8, p0 = r10, r0\n"
991 "(p8) mov b6 = r17\n"
995 "(p7) st1.rel [r9] = r11\n"
998 "(p8) brl.cond.dptk.few xen_check_events\n"
1007 "__xen_intrin_local_irq_restore_direct_end:\n"
1008 ".endp __xen_intrin_local_irq_restore_direct\n"
1011 "__xen_intrin_local_irq_restore_direct_reloc:\n"
1018 #define XEN_PATCH_BUNDLE_ELEM(name, type) \
1020 (void*)xen_ ## name ## _direct_start, \
1021 (void*)xen_ ## name ## _direct_end, \
1022 PARAVIRT_PATCH_TYPE_ ## type, \
1025 XEN_PATCH_BUNDLE_ELEM(
fc,
FC),
1027 XEN_PATCH_BUNDLE_ELEM(get_cpuid, GET_CPUID),
1028 XEN_PATCH_BUNDLE_ELEM(get_pmd, GET_PMD),
1029 XEN_PATCH_BUNDLE_ELEM(ptcga, PTCGA),
1030 XEN_PATCH_BUNDLE_ELEM(get_rr, GET_RR),
1031 XEN_PATCH_BUNDLE_ELEM(set_rr, SET_RR),
1032 XEN_PATCH_BUNDLE_ELEM(set_rr0_to_rr4, SET_RR0_TO_RR4),
1033 XEN_PATCH_BUNDLE_ELEM(ssm_i, SSM_I),
1034 XEN_PATCH_BUNDLE_ELEM(rsm_i, RSM_I),
1035 XEN_PATCH_BUNDLE_ELEM(get_psr_i, GET_PSR_I),
1037 (
void*)__xen_intrin_local_irq_restore_direct_start,
1038 (
void*)__xen_intrin_local_irq_restore_direct_end,
1039 PARAVIRT_PATCH_TYPE_INTRIN_LOCAL_IRQ_RESTORE,
1042 #define XEN_PATCH_BUNDLE_ELEM_GETREG(name, reg) \
1044 xen_get_ ## name ## _direct_start, \
1045 xen_get_ ## name ## _direct_end, \
1046 PARAVIRT_PATCH_TYPE_GETREG + _IA64_REG_ ## reg, \
1049 XEN_PATCH_BUNDLE_ELEM_GETREG(
psr,
PSR),
1050 XEN_PATCH_BUNDLE_ELEM_GETREG(eflag, AR_EFLAG),
1052 XEN_PATCH_BUNDLE_ELEM_GETREG(ivr, CR_IVR),
1053 XEN_PATCH_BUNDLE_ELEM_GETREG(
tpr, CR_TPR),
1055 XEN_PATCH_BUNDLE_ELEM_GETREG(itc, AR_ITC),
1056 XEN_PATCH_BUNDLE_ELEM_GETREG(itm_with_offset, CR_ITM),
1059 #define __XEN_PATCH_BUNDLE_ELEM_SETREG(name, reg) \
1061 xen_ ## name ## _direct_start, \
1062 xen_ ## name ## _direct_end, \
1063 PARAVIRT_PATCH_TYPE_SETREG + _IA64_REG_ ## reg, \
1066 #define XEN_PATCH_BUNDLE_ELEM_SETREG(name, reg) \
1067 __XEN_PATCH_BUNDLE_ELEM_SETREG(set_ ## name, reg)
1069 XEN_PATCH_BUNDLE_ELEM_SETREG(kr0, AR_KR0),
1070 XEN_PATCH_BUNDLE_ELEM_SETREG(kr1, AR_KR1),
1071 XEN_PATCH_BUNDLE_ELEM_SETREG(kr2, AR_KR2),
1072 XEN_PATCH_BUNDLE_ELEM_SETREG(kr3, AR_KR3),
1073 XEN_PATCH_BUNDLE_ELEM_SETREG(kr4, AR_KR4),
1074 XEN_PATCH_BUNDLE_ELEM_SETREG(kr5, AR_KR5),
1075 XEN_PATCH_BUNDLE_ELEM_SETREG(kr6, AR_KR6),
1076 XEN_PATCH_BUNDLE_ELEM_SETREG(kr7, AR_KR7),
1078 XEN_PATCH_BUNDLE_ELEM_SETREG(eflag, AR_EFLAG),
1079 XEN_PATCH_BUNDLE_ELEM_SETREG(
tpr, CR_TPR),
1080 __XEN_PATCH_BUNDLE_ELEM_SETREG(
eoi, CR_EOI),
1082 XEN_PATCH_BUNDLE_ELEM_SETREG(itc, AR_ITC),
1083 XEN_PATCH_BUNDLE_ELEM_SETREG(itm_with_offset, CR_ITM),
1089 const unsigned long nelems =
sizeof(xen_patch_bundle_elems) /
1090 sizeof(xen_patch_bundle_elems[0]);
1094 used = __paravirt_patch_apply_bundle(sbundle, ebundle, type,
1095 xen_patch_bundle_elems, nelems,
1100 return ia64_native_patch_bundle(sbundle, ebundle, type);
1106 case PARAVIRT_PATCH_TYPE_INTRIN_LOCAL_IRQ_RESTORE: {
1107 unsigned long reloc =
1108 __xen_intrin_local_irq_restore_direct_reloc;
1110 __xen_intrin_local_irq_restore_direct_start;
1111 unsigned long tag = (
unsigned long)sbundle + reloc_offset;
1125 #define PARAVIRT_BR_TARGET(name, type) \
1128 PARAVIRT_PATCH_TYPE_BR_ ## type, \
1137 xen_patch_branch(
unsigned long tag,
unsigned long type)