18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * purgatory:  setup code
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2003,2004  Eric Biederman (ebiederm@xmission.com)
68c2ecf20Sopenharmony_ci * Copyright (C) 2014 Red Hat Inc.
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci * This code has been taken from kexec-tools.
98c2ecf20Sopenharmony_ci */
108c2ecf20Sopenharmony_ci#include <linux/linkage.h>
118c2ecf20Sopenharmony_ci#include <asm/purgatory.h>
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci	.text
148c2ecf20Sopenharmony_ci	.balign 16
158c2ecf20Sopenharmony_ci	.code64
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ciSYM_CODE_START(purgatory_start)
188c2ecf20Sopenharmony_ci	/* Load a gdt so I know what the segment registers are */
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 a stack */
308c2ecf20Sopenharmony_ci	leaq	lstack_end(%rip), %rsp
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci	/* Call the C code */
338c2ecf20Sopenharmony_ci	call purgatory
348c2ecf20Sopenharmony_ci	jmp	entry64
358c2ecf20Sopenharmony_ciSYM_CODE_END(purgatory_start)
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci	.section ".rodata"
388c2ecf20Sopenharmony_ci	.balign 16
398c2ecf20Sopenharmony_ciSYM_DATA_START_LOCAL(gdt)
408c2ecf20Sopenharmony_ci	/* 0x00 unusable segment
418c2ecf20Sopenharmony_ci	 * 0x08 unused
428c2ecf20Sopenharmony_ci	 * so use them as the gdt ptr
438c2ecf20Sopenharmony_ci	 */
448c2ecf20Sopenharmony_ci	.word	gdt_end - gdt - 1
458c2ecf20Sopenharmony_ci	.quad	gdt
468c2ecf20Sopenharmony_ci	.word	0, 0, 0
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci	/* 0x10 4GB flat code segment */
498c2ecf20Sopenharmony_ci	.word	0xFFFF, 0x0000, 0x9A00, 0x00AF
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci	/* 0x18 4GB flat data segment */
528c2ecf20Sopenharmony_ci	.word	0xFFFF, 0x0000, 0x9200, 0x00CF
538c2ecf20Sopenharmony_ciSYM_DATA_END_LABEL(gdt, SYM_L_LOCAL, gdt_end)
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci	.bss
568c2ecf20Sopenharmony_ci	.balign 4096
578c2ecf20Sopenharmony_ciSYM_DATA_START_LOCAL(lstack)
588c2ecf20Sopenharmony_ci	.skip 4096
598c2ecf20Sopenharmony_ciSYM_DATA_END_LABEL(lstack, SYM_L_LOCAL, lstack_end)
60