xref: /openbmc/u-boot/arch/x86/lib/fsp/fsp_car.S (revision 5c8fd32b)
1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
4 */
5
6#include <config.h>
7#include <asm/post.h>
8
9.globl car_init
10car_init:
11	/*
12	 * Note: ebp holds the BIST value (built-in self test) so far, but ebp
13	 * will be destroyed through the FSP call, thus we have to test the
14	 * BIST value here before we call into FSP.
15	 */
16	test	%ebp, %ebp
17	jz	car_init_start
18	post_code(POST_BIST_FAILURE)
19	jmp	die
20
21car_init_start:
22	post_code(POST_CAR_START)
23	lea	find_fsp_header_romstack, %esp
24	jmp	find_fsp_header
25
26find_fsp_header_ret:
27	/* EAX points to FSP_INFO_HEADER */
28	mov	%eax, %ebp
29
30	/* sanity test */
31	cmp	$CONFIG_FSP_ADDR, %eax
32	jb	die
33
34	/* calculate TempRamInitEntry address */
35	mov	0x30(%ebp), %eax
36	add	0x1c(%ebp), %eax
37
38	/* call FSP TempRamInitEntry to setup temporary stack */
39	lea	temp_ram_init_romstack, %esp
40	jmp	*%eax
41
42temp_ram_init_ret:
43	addl	$4, %esp
44	cmp	$0, %eax
45	jnz	car_init_fail
46
47	post_code(POST_CAR_CPU_CACHE)
48
49	/*
50	 * The FSP TempRamInit initializes the ecx and edx registers to
51	 * point to a temporary but writable memory range (Cache-As-RAM).
52	 * ecx: the start of this temporary memory range,
53	 * edx: the end of this range.
54	 */
55
56	/* stack grows down from top of CAR */
57	movl	%edx, %esp
58	subl	$4, %esp
59
60	xor	%esi, %esi
61	jmp	car_init_done
62
63.global fsp_init_done
64fsp_init_done:
65	/*
66	 * We come here from fsp_continue() with eax pointing to the HOB list.
67	 * Save eax to esi temporarily.
68	 */
69	movl	%eax, %esi
70
71car_init_done:
72	/*
73	 * Re-initialize the ebp (BIST) to zero, as we already reach here
74	 * which means we passed BIST testing before.
75	 */
76	xorl	%ebp, %ebp
77	jmp	car_init_ret
78
79car_init_fail:
80	post_code(POST_CAR_FAILURE)
81
82die:
83	hlt
84	jmp	die
85	hlt
86
87	/*
88	 * The function call before CAR initialization is tricky. It cannot
89	 * be called using the 'call' instruction but only the 'jmp' with
90	 * the help of a handcrafted stack in the ROM. The stack needs to
91	 * contain the function return address as well as the parameters.
92	 */
93	.balign	4
94find_fsp_header_romstack:
95	.long	find_fsp_header_ret
96
97	.balign	4
98temp_ram_init_romstack:
99	.long	temp_ram_init_ret
100	.long	temp_ram_init_params
101temp_ram_init_params:
102_dt_ucode_base_size:
103	/* These next two fields are filled in by ifdtool */
104.globl ucode_base
105ucode_base:	/* Declared in microcode.h */
106	.long	0			/* microcode base */
107.globl ucode_size
108ucode_size:	/* Declared in microcode.h */
109	.long	0			/* microcode size */
110	.long	CONFIG_SYS_MONITOR_BASE	/* code region base */
111	.long	CONFIG_SYS_MONITOR_LEN	/* code region size */
112