162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2003,2004  Eric Biederman (ebiederm@xmission.com)
462306a36Sopenharmony_ci * Copyright (C) 2014  Red Hat Inc.
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci * Author(s): Vivek Goyal <vgoyal@redhat.com>
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * This code has been taken from kexec-tools.
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include <linux/linkage.h>
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci	.text
1462306a36Sopenharmony_ci	.balign 16
1562306a36Sopenharmony_ci	.code64
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ciSYM_CODE_START(entry64)
1862306a36Sopenharmony_ci	/* Setup a gdt that should be preserved */
1962306a36Sopenharmony_ci	lgdt gdt(%rip)
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci	/* load the data segments */
2262306a36Sopenharmony_ci	movl    $0x18, %eax     /* data segment */
2362306a36Sopenharmony_ci	movl    %eax, %ds
2462306a36Sopenharmony_ci	movl    %eax, %es
2562306a36Sopenharmony_ci	movl    %eax, %ss
2662306a36Sopenharmony_ci	movl    %eax, %fs
2762306a36Sopenharmony_ci	movl    %eax, %gs
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci	/* Setup new stack */
3062306a36Sopenharmony_ci	leaq    stack_init(%rip), %rsp
3162306a36Sopenharmony_ci	pushq   $0x10 /* CS */
3262306a36Sopenharmony_ci	leaq    new_cs_exit(%rip), %rax
3362306a36Sopenharmony_ci	pushq   %rax
3462306a36Sopenharmony_ci	lretq
3562306a36Sopenharmony_cinew_cs_exit:
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci	/* Load the registers */
3862306a36Sopenharmony_ci	movq	rax(%rip), %rax
3962306a36Sopenharmony_ci	movq	rbx(%rip), %rbx
4062306a36Sopenharmony_ci	movq	rcx(%rip), %rcx
4162306a36Sopenharmony_ci	movq	rdx(%rip), %rdx
4262306a36Sopenharmony_ci	movq	rsi(%rip), %rsi
4362306a36Sopenharmony_ci	movq	rdi(%rip), %rdi
4462306a36Sopenharmony_ci	movq    rsp(%rip), %rsp
4562306a36Sopenharmony_ci	movq	rbp(%rip), %rbp
4662306a36Sopenharmony_ci	movq	r8(%rip), %r8
4762306a36Sopenharmony_ci	movq	r9(%rip), %r9
4862306a36Sopenharmony_ci	movq	r10(%rip), %r10
4962306a36Sopenharmony_ci	movq	r11(%rip), %r11
5062306a36Sopenharmony_ci	movq	r12(%rip), %r12
5162306a36Sopenharmony_ci	movq	r13(%rip), %r13
5262306a36Sopenharmony_ci	movq	r14(%rip), %r14
5362306a36Sopenharmony_ci	movq	r15(%rip), %r15
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci	/* Jump to the new code... */
5662306a36Sopenharmony_ci	jmpq	*rip(%rip)
5762306a36Sopenharmony_ciSYM_CODE_END(entry64)
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci	.section ".rodata"
6062306a36Sopenharmony_ci	.balign 4
6162306a36Sopenharmony_ciSYM_DATA_START(entry64_regs)
6262306a36Sopenharmony_cirax:	.quad 0x0
6362306a36Sopenharmony_circx:	.quad 0x0
6462306a36Sopenharmony_cirdx:	.quad 0x0
6562306a36Sopenharmony_cirbx:	.quad 0x0
6662306a36Sopenharmony_cirsp:	.quad 0x0
6762306a36Sopenharmony_cirbp:	.quad 0x0
6862306a36Sopenharmony_cirsi:	.quad 0x0
6962306a36Sopenharmony_cirdi:	.quad 0x0
7062306a36Sopenharmony_cir8:	.quad 0x0
7162306a36Sopenharmony_cir9:	.quad 0x0
7262306a36Sopenharmony_cir10:	.quad 0x0
7362306a36Sopenharmony_cir11:	.quad 0x0
7462306a36Sopenharmony_cir12:	.quad 0x0
7562306a36Sopenharmony_cir13:	.quad 0x0
7662306a36Sopenharmony_cir14:	.quad 0x0
7762306a36Sopenharmony_cir15:	.quad 0x0
7862306a36Sopenharmony_cirip:	.quad 0x0
7962306a36Sopenharmony_ciSYM_DATA_END(entry64_regs)
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci	/* GDT */
8262306a36Sopenharmony_ci	.section ".rodata"
8362306a36Sopenharmony_ci	.balign 16
8462306a36Sopenharmony_ciSYM_DATA_START_LOCAL(gdt)
8562306a36Sopenharmony_ci	/*
8662306a36Sopenharmony_ci	 * 0x00 unusable segment
8762306a36Sopenharmony_ci	 * 0x08 unused
8862306a36Sopenharmony_ci	 * so use them as gdt ptr
8962306a36Sopenharmony_ci	 */
9062306a36Sopenharmony_ci	.word gdt_end - gdt - 1
9162306a36Sopenharmony_ci	.quad gdt
9262306a36Sopenharmony_ci	.word 0, 0, 0
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci	/* 0x10 4GB flat code segment */
9562306a36Sopenharmony_ci	.word 0xFFFF, 0x0000, 0x9A00, 0x00AF
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci	/* 0x18 4GB flat data segment */
9862306a36Sopenharmony_ci	.word 0xFFFF, 0x0000, 0x9200, 0x00CF
9962306a36Sopenharmony_ciSYM_DATA_END_LABEL(gdt, SYM_L_LOCAL, gdt_end)
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ciSYM_DATA_START_LOCAL(stack)
10262306a36Sopenharmony_ci	.quad   0, 0
10362306a36Sopenharmony_ciSYM_DATA_END_LABEL(stack, SYM_L_LOCAL, stack_init)
104