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