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