xref: /linux/arch/x86/purgatory/entry64.S (revision c95baf12f5077419db01313ab61c2aac007d40cd)
140b0b3f8SThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-only */
28fc5b4d4SVivek Goyal/*
38fc5b4d4SVivek Goyal * Copyright (C) 2003,2004  Eric Biederman (ebiederm@xmission.com)
48fc5b4d4SVivek Goyal * Copyright (C) 2014  Red Hat Inc.
58fc5b4d4SVivek Goyal
68fc5b4d4SVivek Goyal * Author(s): Vivek Goyal <vgoyal@redhat.com>
78fc5b4d4SVivek Goyal *
88fc5b4d4SVivek Goyal * This code has been taken from kexec-tools.
98fc5b4d4SVivek Goyal */
108fc5b4d4SVivek Goyal
11*b16fed65SJiri Slaby#include <linux/linkage.h>
12*b16fed65SJiri Slaby
138fc5b4d4SVivek Goyal	.text
148fc5b4d4SVivek Goyal	.balign 16
158fc5b4d4SVivek Goyal	.code64
168fc5b4d4SVivek Goyal
17*b16fed65SJiri SlabySYM_CODE_START(entry64)
188fc5b4d4SVivek Goyal	/* Setup a gdt that should be preserved */
198fc5b4d4SVivek Goyal	lgdt gdt(%rip)
208fc5b4d4SVivek Goyal
218fc5b4d4SVivek Goyal	/* load the data segments */
228fc5b4d4SVivek Goyal	movl    $0x18, %eax     /* data segment */
238fc5b4d4SVivek Goyal	movl    %eax, %ds
248fc5b4d4SVivek Goyal	movl    %eax, %es
258fc5b4d4SVivek Goyal	movl    %eax, %ss
268fc5b4d4SVivek Goyal	movl    %eax, %fs
278fc5b4d4SVivek Goyal	movl    %eax, %gs
288fc5b4d4SVivek Goyal
298fc5b4d4SVivek Goyal	/* Setup new stack */
308fc5b4d4SVivek Goyal	leaq    stack_init(%rip), %rsp
318fc5b4d4SVivek Goyal	pushq   $0x10 /* CS */
328fc5b4d4SVivek Goyal	leaq    new_cs_exit(%rip), %rax
338fc5b4d4SVivek Goyal	pushq   %rax
348fc5b4d4SVivek Goyal	lretq
358fc5b4d4SVivek Goyalnew_cs_exit:
368fc5b4d4SVivek Goyal
378fc5b4d4SVivek Goyal	/* Load the registers */
388fc5b4d4SVivek Goyal	movq	rax(%rip), %rax
398fc5b4d4SVivek Goyal	movq	rbx(%rip), %rbx
408fc5b4d4SVivek Goyal	movq	rcx(%rip), %rcx
418fc5b4d4SVivek Goyal	movq	rdx(%rip), %rdx
428fc5b4d4SVivek Goyal	movq	rsi(%rip), %rsi
438fc5b4d4SVivek Goyal	movq	rdi(%rip), %rdi
448fc5b4d4SVivek Goyal	movq    rsp(%rip), %rsp
458fc5b4d4SVivek Goyal	movq	rbp(%rip), %rbp
468fc5b4d4SVivek Goyal	movq	r8(%rip), %r8
478fc5b4d4SVivek Goyal	movq	r9(%rip), %r9
488fc5b4d4SVivek Goyal	movq	r10(%rip), %r10
498fc5b4d4SVivek Goyal	movq	r11(%rip), %r11
508fc5b4d4SVivek Goyal	movq	r12(%rip), %r12
518fc5b4d4SVivek Goyal	movq	r13(%rip), %r13
528fc5b4d4SVivek Goyal	movq	r14(%rip), %r14
538fc5b4d4SVivek Goyal	movq	r15(%rip), %r15
548fc5b4d4SVivek Goyal
558fc5b4d4SVivek Goyal	/* Jump to the new code... */
568fc5b4d4SVivek Goyal	jmpq	*rip(%rip)
57*b16fed65SJiri SlabySYM_CODE_END(entry64)
588fc5b4d4SVivek Goyal
598fc5b4d4SVivek Goyal	.section ".rodata"
608fc5b4d4SVivek Goyal	.balign 4
61*b16fed65SJiri SlabySYM_DATA_START(entry64_regs)
628fc5b4d4SVivek Goyalrax:	.quad 0x0
638fc5b4d4SVivek Goyalrcx:	.quad 0x0
648fc5b4d4SVivek Goyalrdx:	.quad 0x0
65dd5f7260SVivek Goyalrbx:	.quad 0x0
668fc5b4d4SVivek Goyalrsp:	.quad 0x0
678fc5b4d4SVivek Goyalrbp:	.quad 0x0
68dd5f7260SVivek Goyalrsi:	.quad 0x0
69dd5f7260SVivek Goyalrdi:	.quad 0x0
708fc5b4d4SVivek Goyalr8:	.quad 0x0
718fc5b4d4SVivek Goyalr9:	.quad 0x0
728fc5b4d4SVivek Goyalr10:	.quad 0x0
738fc5b4d4SVivek Goyalr11:	.quad 0x0
748fc5b4d4SVivek Goyalr12:	.quad 0x0
758fc5b4d4SVivek Goyalr13:	.quad 0x0
768fc5b4d4SVivek Goyalr14:	.quad 0x0
778fc5b4d4SVivek Goyalr15:	.quad 0x0
788fc5b4d4SVivek Goyalrip:	.quad 0x0
79*b16fed65SJiri SlabySYM_DATA_END(entry64_regs)
808fc5b4d4SVivek Goyal
818fc5b4d4SVivek Goyal	/* GDT */
828fc5b4d4SVivek Goyal	.section ".rodata"
838fc5b4d4SVivek Goyal	.balign 16
84*b16fed65SJiri SlabySYM_DATA_START_LOCAL(gdt)
85*b16fed65SJiri Slaby	/*
86*b16fed65SJiri Slaby	 * 0x00 unusable segment
878fc5b4d4SVivek Goyal	 * 0x08 unused
888fc5b4d4SVivek Goyal	 * so use them as gdt ptr
898fc5b4d4SVivek Goyal	 */
908fc5b4d4SVivek Goyal	.word gdt_end - gdt - 1
918fc5b4d4SVivek Goyal	.quad gdt
928fc5b4d4SVivek Goyal	.word 0, 0, 0
938fc5b4d4SVivek Goyal
948fc5b4d4SVivek Goyal	/* 0x10 4GB flat code segment */
958fc5b4d4SVivek Goyal	.word 0xFFFF, 0x0000, 0x9A00, 0x00AF
968fc5b4d4SVivek Goyal
978fc5b4d4SVivek Goyal	/* 0x18 4GB flat data segment */
988fc5b4d4SVivek Goyal	.word 0xFFFF, 0x0000, 0x9200, 0x00CF
99*b16fed65SJiri SlabySYM_DATA_END_LABEL(gdt, SYM_L_LOCAL, gdt_end)
100*b16fed65SJiri Slaby
101*b16fed65SJiri SlabySYM_DATA_START_LOCAL(stack)
102*b16fed65SJiri Slaby	.quad   0, 0
103*b16fed65SJiri SlabySYM_DATA_END_LABEL(stack, SYM_L_LOCAL, stack_init)
104