summaryrefslogtreecommitdiffstats
path: root/src/arch/x86/assembly_entry.S
blob: b0e15dc7003b03781bf3e60082880b893f042510 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/* SPDX-License-Identifier: GPL-2.0-only */

#include <rules.h>

/*
 * This path is for stages that are post bootblock. The gdt is reloaded
 * to accommodate platforms that are executing out of CAR. In order to
 * continue with C code execution one needs to set stack pointer and
 * clear .bss variables that are stage specific.
 */

#if CONFIG(RESET_VECTOR_IN_RAM)
	#define _STACK_TOP _eearlyram_stack
#else
	#define _STACK_TOP _ecar_stack
#endif

#if ENV_X86_64
.code64
#else
.code32
#endif

.section ".text._start", "ax", @progbits
.global _start
_start:

	/* Migrate GDT to this text segment */
#if ENV_X86_64
	call	gdt_init64
#else
	call	gdt_init
#endif

	/* reset stack pointer to CAR/EARLYRAM stack */
	mov	$_STACK_TOP, %esp

#if CONFIG(COOP_MULTITASKING)
	/* Push the thread pointer. */
	push	$0
#endif
	/* Push the CPU index and struct CPU */
	push	$0
	push	$0

	/* clear .bss section as it is not shared */
	cld
	xor	%eax, %eax
	movl	$(_ebss), %ecx
	movl	$(_bss), %edi
	sub	%edi, %ecx
	shrl	$2, %ecx
	rep	stosl

#if ((ENV_SEPARATE_VERSTAGE && CONFIG(VERSTAGE_DEBUG_SPINLOOP)) \
	|| (ENV_ROMSTAGE && CONFIG(ROMSTAGE_DEBUG_SPINLOOP)))

	/* Wait for a JTAG debugger to break in and set EBX non-zero */
	xor	%ebx, %ebx

debug_spinloop:
	cmp	$0, %ebx
	jz	debug_spinloop
#endif

	andl	$0xfffffff0, %esp
#if CONFIG(IDT_IN_EVERY_STAGE)
	call	exception_init
#endif

#if CONFIG(ASAN_IN_ROMSTAGE)
	call	asan_init
#endif
	call	car_stage_entry

	/* Expect to never return. */
1:
	jmp	1b