18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2003,2004  Eric Biederman (ebiederm@xmission.com)
48c2ecf20Sopenharmony_ci * Copyright (C) 2014  Red Hat Inc.
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci * Author(s): Vivek Goyal <vgoyal@redhat.com>
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci * This code has been taken from kexec-tools.
98c2ecf20Sopenharmony_ci */
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#include <linux/linkage.h>
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci	.text
148c2ecf20Sopenharmony_ci	.balign 16
158c2ecf20Sopenharmony_ci	.code64
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ciSYM_CODE_START(entry64)
188c2ecf20Sopenharmony_ci	/* Setup a gdt that should be preserved */
198c2ecf20Sopenharmony_ci	lgdt gdt(%rip)
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci	/* load the data segments */
228c2ecf20Sopenharmony_ci	movl    $0x18, %eax     /* data segment */
238c2ecf20Sopenharmony_ci	movl    %eax, %ds
248c2ecf20Sopenharmony_ci	movl    %eax, %es
258c2ecf20Sopenharmony_ci	movl    %eax, %ss
268c2ecf20Sopenharmony_ci	movl    %eax, %fs
278c2ecf20Sopenharmony_ci	movl    %eax, %gs
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci	/* Setup new stack */
308c2ecf20Sopenharmony_ci	leaq    stack_init(%rip), %rsp
318c2ecf20Sopenharmony_ci	pushq   $0x10 /* CS */
328c2ecf20Sopenharmony_ci	leaq    new_cs_exit(%rip), %rax
338c2ecf20Sopenharmony_ci	pushq   %rax
348c2ecf20Sopenharmony_ci	lretq
358c2ecf20Sopenharmony_cinew_cs_exit:
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci	/* Load the registers */
388c2ecf20Sopenharmony_ci	movq	rax(%rip), %rax
398c2ecf20Sopenharmony_ci	movq	rbx(%rip), %rbx
408c2ecf20Sopenharmony_ci	movq	rcx(%rip), %rcx
418c2ecf20Sopenharmony_ci	movq	rdx(%rip), %rdx
428c2ecf20Sopenharmony_ci	movq	rsi(%rip), %rsi
438c2ecf20Sopenharmony_ci	movq	rdi(%rip), %rdi
448c2ecf20Sopenharmony_ci	movq    rsp(%rip), %rsp
458c2ecf20Sopenharmony_ci	movq	rbp(%rip), %rbp
468c2ecf20Sopenharmony_ci	movq	r8(%rip), %r8
478c2ecf20Sopenharmony_ci	movq	r9(%rip), %r9
488c2ecf20Sopenharmony_ci	movq	r10(%rip), %r10
498c2ecf20Sopenharmony_ci	movq	r11(%rip), %r11
508c2ecf20Sopenharmony_ci	movq	r12(%rip), %r12
518c2ecf20Sopenharmony_ci	movq	r13(%rip), %r13
528c2ecf20Sopenharmony_ci	movq	r14(%rip), %r14
538c2ecf20Sopenharmony_ci	movq	r15(%rip), %r15
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci	/* Jump to the new code... */
568c2ecf20Sopenharmony_ci	jmpq	*rip(%rip)
578c2ecf20Sopenharmony_ciSYM_CODE_END(entry64)
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci	.section ".rodata"
608c2ecf20Sopenharmony_ci	.balign 4
618c2ecf20Sopenharmony_ciSYM_DATA_START(entry64_regs)
628c2ecf20Sopenharmony_cirax:	.quad 0x0
638c2ecf20Sopenharmony_circx:	.quad 0x0
648c2ecf20Sopenharmony_cirdx:	.quad 0x0
658c2ecf20Sopenharmony_cirbx:	.quad 0x0
668c2ecf20Sopenharmony_cirsp:	.quad 0x0
678c2ecf20Sopenharmony_cirbp:	.quad 0x0
688c2ecf20Sopenharmony_cirsi:	.quad 0x0
698c2ecf20Sopenharmony_cirdi:	.quad 0x0
708c2ecf20Sopenharmony_cir8:	.quad 0x0
718c2ecf20Sopenharmony_cir9:	.quad 0x0
728c2ecf20Sopenharmony_cir10:	.quad 0x0
738c2ecf20Sopenharmony_cir11:	.quad 0x0
748c2ecf20Sopenharmony_cir12:	.quad 0x0
758c2ecf20Sopenharmony_cir13:	.quad 0x0
768c2ecf20Sopenharmony_cir14:	.quad 0x0
778c2ecf20Sopenharmony_cir15:	.quad 0x0
788c2ecf20Sopenharmony_cirip:	.quad 0x0
798c2ecf20Sopenharmony_ciSYM_DATA_END(entry64_regs)
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci	/* GDT */
828c2ecf20Sopenharmony_ci	.section ".rodata"
838c2ecf20Sopenharmony_ci	.balign 16
848c2ecf20Sopenharmony_ciSYM_DATA_START_LOCAL(gdt)
858c2ecf20Sopenharmony_ci	/*
868c2ecf20Sopenharmony_ci	 * 0x00 unusable segment
878c2ecf20Sopenharmony_ci	 * 0x08 unused
888c2ecf20Sopenharmony_ci	 * so use them as gdt ptr
898c2ecf20Sopenharmony_ci	 */
908c2ecf20Sopenharmony_ci	.word gdt_end - gdt - 1
918c2ecf20Sopenharmony_ci	.quad gdt
928c2ecf20Sopenharmony_ci	.word 0, 0, 0
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci	/* 0x10 4GB flat code segment */
958c2ecf20Sopenharmony_ci	.word 0xFFFF, 0x0000, 0x9A00, 0x00AF
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci	/* 0x18 4GB flat data segment */
988c2ecf20Sopenharmony_ci	.word 0xFFFF, 0x0000, 0x9200, 0x00CF
998c2ecf20Sopenharmony_ciSYM_DATA_END_LABEL(gdt, SYM_L_LOCAL, gdt_end)
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ciSYM_DATA_START_LOCAL(stack)
1028c2ecf20Sopenharmony_ci	.quad   0, 0
1038c2ecf20Sopenharmony_ciSYM_DATA_END_LABEL(stack, SYM_L_LOCAL, stack_init)
104