162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/* Xen-specific pieces of head.S, intended to be included in the right
362306a36Sopenharmony_ci	place in head.S */
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#ifdef CONFIG_XEN
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include <linux/elfnote.h>
862306a36Sopenharmony_ci#include <linux/init.h>
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <asm/boot.h>
1162306a36Sopenharmony_ci#include <asm/asm.h>
1262306a36Sopenharmony_ci#include <asm/msr.h>
1362306a36Sopenharmony_ci#include <asm/page_types.h>
1462306a36Sopenharmony_ci#include <asm/percpu.h>
1562306a36Sopenharmony_ci#include <asm/unwind_hints.h>
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#include <xen/interface/elfnote.h>
1862306a36Sopenharmony_ci#include <xen/interface/features.h>
1962306a36Sopenharmony_ci#include <xen/interface/xen.h>
2062306a36Sopenharmony_ci#include <xen/interface/xen-mca.h>
2162306a36Sopenharmony_ci#include <asm/xen/interface.h>
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci.pushsection .noinstr.text, "ax"
2462306a36Sopenharmony_ci	.balign PAGE_SIZE
2562306a36Sopenharmony_ciSYM_CODE_START(hypercall_page)
2662306a36Sopenharmony_ci	.rept (PAGE_SIZE / 32)
2762306a36Sopenharmony_ci		UNWIND_HINT_FUNC
2862306a36Sopenharmony_ci		ANNOTATE_NOENDBR
2962306a36Sopenharmony_ci		ANNOTATE_UNRET_SAFE
3062306a36Sopenharmony_ci		ret
3162306a36Sopenharmony_ci		/*
3262306a36Sopenharmony_ci		 * Xen will write the hypercall page, and sort out ENDBR.
3362306a36Sopenharmony_ci		 */
3462306a36Sopenharmony_ci		.skip 31, 0xcc
3562306a36Sopenharmony_ci	.endr
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci#define HYPERCALL(n) \
3862306a36Sopenharmony_ci	.equ xen_hypercall_##n, hypercall_page + __HYPERVISOR_##n * 32; \
3962306a36Sopenharmony_ci	.type xen_hypercall_##n, @function; .size xen_hypercall_##n, 32
4062306a36Sopenharmony_ci#include <asm/xen-hypercalls.h>
4162306a36Sopenharmony_ci#undef HYPERCALL
4262306a36Sopenharmony_ciSYM_CODE_END(hypercall_page)
4362306a36Sopenharmony_ci.popsection
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci#ifdef CONFIG_XEN_PV
4662306a36Sopenharmony_ci	__INIT
4762306a36Sopenharmony_ciSYM_CODE_START(startup_xen)
4862306a36Sopenharmony_ci	UNWIND_HINT_END_OF_STACK
4962306a36Sopenharmony_ci	ANNOTATE_NOENDBR
5062306a36Sopenharmony_ci	cld
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci	leaq	(__end_init_task - PTREGS_SIZE)(%rip), %rsp
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci	/* Set up %gs.
5562306a36Sopenharmony_ci	 *
5662306a36Sopenharmony_ci	 * The base of %gs always points to fixed_percpu_data.  If the
5762306a36Sopenharmony_ci	 * stack protector canary is enabled, it is located at %gs:40.
5862306a36Sopenharmony_ci	 * Note that, on SMP, the boot cpu uses init data section until
5962306a36Sopenharmony_ci	 * the per cpu areas are set up.
6062306a36Sopenharmony_ci	 */
6162306a36Sopenharmony_ci	movl	$MSR_GS_BASE,%ecx
6262306a36Sopenharmony_ci	movq	$INIT_PER_CPU_VAR(fixed_percpu_data),%rax
6362306a36Sopenharmony_ci	cdq
6462306a36Sopenharmony_ci	wrmsr
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci	mov	%rsi, %rdi
6762306a36Sopenharmony_ci	call xen_start_kernel
6862306a36Sopenharmony_ciSYM_CODE_END(startup_xen)
6962306a36Sopenharmony_ci	__FINIT
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci#ifdef CONFIG_XEN_PV_SMP
7262306a36Sopenharmony_ci.pushsection .text
7362306a36Sopenharmony_ciSYM_CODE_START(asm_cpu_bringup_and_idle)
7462306a36Sopenharmony_ci	UNWIND_HINT_END_OF_STACK
7562306a36Sopenharmony_ci	ENDBR
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci	call cpu_bringup_and_idle
7862306a36Sopenharmony_ciSYM_CODE_END(asm_cpu_bringup_and_idle)
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ciSYM_CODE_START(xen_cpu_bringup_again)
8162306a36Sopenharmony_ci	UNWIND_HINT_FUNC
8262306a36Sopenharmony_ci	mov	%rdi, %rsp
8362306a36Sopenharmony_ci	UNWIND_HINT_REGS
8462306a36Sopenharmony_ci	call	cpu_bringup_and_idle
8562306a36Sopenharmony_ciSYM_CODE_END(xen_cpu_bringup_again)
8662306a36Sopenharmony_ci.popsection
8762306a36Sopenharmony_ci#endif
8862306a36Sopenharmony_ci#endif
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci	ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS,       .asciz "linux")
9162306a36Sopenharmony_ci	ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION,  .asciz "2.6")
9262306a36Sopenharmony_ci	ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION,    .asciz "xen-3.0")
9362306a36Sopenharmony_ci#ifdef CONFIG_XEN_PV
9462306a36Sopenharmony_ci	ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE,      _ASM_PTR __START_KERNEL_map)
9562306a36Sopenharmony_ci	/* Map the p2m table to a 512GB-aligned user address. */
9662306a36Sopenharmony_ci	ELFNOTE(Xen, XEN_ELFNOTE_INIT_P2M,       .quad (PUD_SIZE * PTRS_PER_PUD))
9762306a36Sopenharmony_ci	ELFNOTE(Xen, XEN_ELFNOTE_ENTRY,          _ASM_PTR startup_xen)
9862306a36Sopenharmony_ci	ELFNOTE(Xen, XEN_ELFNOTE_FEATURES,       .ascii "!writable_page_tables")
9962306a36Sopenharmony_ci	ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE,       .asciz "yes")
10062306a36Sopenharmony_ci	ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID,
10162306a36Sopenharmony_ci		.quad _PAGE_PRESENT; .quad _PAGE_PRESENT)
10262306a36Sopenharmony_ci	ELFNOTE(Xen, XEN_ELFNOTE_MOD_START_PFN,  .long 1)
10362306a36Sopenharmony_ci	ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET,   _ASM_PTR 0)
10462306a36Sopenharmony_ci# define FEATURES_PV (1 << XENFEAT_writable_page_tables)
10562306a36Sopenharmony_ci#else
10662306a36Sopenharmony_ci# define FEATURES_PV 0
10762306a36Sopenharmony_ci#endif
10862306a36Sopenharmony_ci#ifdef CONFIG_XEN_PVH
10962306a36Sopenharmony_ci# define FEATURES_PVH (1 << XENFEAT_linux_rsdp_unrestricted)
11062306a36Sopenharmony_ci#else
11162306a36Sopenharmony_ci# define FEATURES_PVH 0
11262306a36Sopenharmony_ci#endif
11362306a36Sopenharmony_ci#ifdef CONFIG_XEN_DOM0
11462306a36Sopenharmony_ci# define FEATURES_DOM0 (1 << XENFEAT_dom0)
11562306a36Sopenharmony_ci#else
11662306a36Sopenharmony_ci# define FEATURES_DOM0 0
11762306a36Sopenharmony_ci#endif
11862306a36Sopenharmony_ci	ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, _ASM_PTR hypercall_page)
11962306a36Sopenharmony_ci	ELFNOTE(Xen, XEN_ELFNOTE_SUPPORTED_FEATURES,
12062306a36Sopenharmony_ci		.long FEATURES_PV | FEATURES_PVH | FEATURES_DOM0)
12162306a36Sopenharmony_ci	ELFNOTE(Xen, XEN_ELFNOTE_LOADER,         .asciz "generic")
12262306a36Sopenharmony_ci	ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long 1)
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci#endif /*CONFIG_XEN */
125