Bin Meng | 08e484c | 2014-12-17 15:50:36 +0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> |
| 3 | * |
| 4 | * SPDX-License-Identifier: GPL-2.0+ |
| 5 | */ |
| 6 | |
| 7 | #include <config.h> |
| 8 | #include <asm/post.h> |
| 9 | |
| 10 | .globl car_init |
| 11 | car_init: |
| 12 | /* |
| 13 | * Note: ebp holds the BIST value (built-in self test) so far, but ebp |
| 14 | * will be destroyed through the FSP call, thus we have to test the |
| 15 | * BIST value here before we call into FSP. |
| 16 | */ |
| 17 | test %ebp, %ebp |
| 18 | jz car_init_start |
| 19 | post_code(POST_BIST_FAILURE) |
| 20 | jmp die |
| 21 | |
| 22 | car_init_start: |
| 23 | post_code(POST_CAR_START) |
| 24 | lea find_fsp_header_romstack, %esp |
| 25 | jmp find_fsp_header |
| 26 | |
| 27 | find_fsp_header_ret: |
| 28 | /* EAX points to FSP_INFO_HEADER */ |
| 29 | mov %eax, %ebp |
| 30 | |
| 31 | /* sanity test */ |
Bin Meng | 293f497 | 2014-12-17 15:50:42 +0800 | [diff] [blame] | 32 | cmp $CONFIG_FSP_ADDR, %eax |
Bin Meng | 08e484c | 2014-12-17 15:50:36 +0800 | [diff] [blame] | 33 | jb die |
| 34 | |
| 35 | /* calculate TempRamInitEntry address */ |
| 36 | mov 0x30(%ebp), %eax |
| 37 | add 0x1c(%ebp), %eax |
| 38 | |
| 39 | /* call FSP TempRamInitEntry to setup temporary stack */ |
| 40 | lea temp_ram_init_romstack, %esp |
| 41 | jmp *%eax |
| 42 | |
| 43 | temp_ram_init_ret: |
| 44 | addl $4, %esp |
| 45 | cmp $0, %eax |
| 46 | jnz car_init_fail |
| 47 | |
| 48 | post_code(POST_CAR_CPU_CACHE) |
| 49 | |
| 50 | /* |
| 51 | * The FSP TempRamInit initializes the ecx and edx registers to |
| 52 | * point to a temporary but writable memory range (Cache-As-RAM). |
| 53 | * ecx: the start of this temporary memory range, |
| 54 | * edx: the end of this range. |
| 55 | */ |
| 56 | |
| 57 | /* stack grows down from top of CAR */ |
| 58 | movl %edx, %esp |
| 59 | |
| 60 | /* |
| 61 | * TODO: |
| 62 | * |
| 63 | * According to FSP architecture spec, the fsp_init() will not return |
| 64 | * to its caller, instead it requires the bootloader to provide a |
| 65 | * so-called continuation function to pass into the FSP as a parameter |
| 66 | * of fsp_init, and fsp_init() will call that continuation function |
| 67 | * directly. |
| 68 | * |
| 69 | * The call to fsp_init() may need to be moved out of the car_init() |
| 70 | * to cpu_init_f() with the help of some inline assembly codes. |
| 71 | * Note there is another issue that fsp_init() will setup another stack |
| 72 | * using the fsp_init parameter stack_top after DRAM is initialized, |
| 73 | * which means any data on the previous stack (on the CAR) gets lost |
| 74 | * (ie: U-Boot global_data). FSP is supposed to support such scenario, |
| 75 | * however it does not work. This should be revisited in the future. |
| 76 | */ |
| 77 | movl $CONFIG_FSP_TEMP_RAM_ADDR, %eax |
| 78 | xorl %edx, %edx |
| 79 | xorl %ecx, %ecx |
| 80 | call fsp_init |
| 81 | |
| 82 | .global fsp_init_done |
| 83 | fsp_init_done: |
| 84 | /* |
| 85 | * We come here from FspInit with eax pointing to the HOB list. |
| 86 | * Save eax to esi temporarily. |
| 87 | */ |
| 88 | movl %eax, %esi |
| 89 | /* |
| 90 | * Re-initialize the ebp (BIST) to zero, as we already reach here |
| 91 | * which means we passed BIST testing before. |
| 92 | */ |
| 93 | xorl %ebp, %ebp |
| 94 | jmp car_init_ret |
| 95 | |
| 96 | car_init_fail: |
| 97 | post_code(POST_CAR_FAILURE) |
| 98 | |
| 99 | die: |
| 100 | hlt |
| 101 | jmp die |
| 102 | hlt |
| 103 | |
| 104 | /* |
| 105 | * The function call before CAR initialization is tricky. It cannot |
| 106 | * be called using the 'call' instruction but only the 'jmp' with |
| 107 | * the help of a handcrafted stack in the ROM. The stack needs to |
| 108 | * contain the function return address as well as the parameters. |
| 109 | */ |
| 110 | .balign 4 |
| 111 | find_fsp_header_romstack: |
| 112 | .long find_fsp_header_ret |
| 113 | |
| 114 | .balign 4 |
| 115 | temp_ram_init_romstack: |
| 116 | .long temp_ram_init_ret |
| 117 | .long temp_ram_init_params |
| 118 | temp_ram_init_params: |
Simon Glass | 8bfe066 | 2014-12-17 15:50:37 +0800 | [diff] [blame] | 119 | _dt_ucode_base_size: |
| 120 | /* These next two fields are filled in by ifdtool */ |
| 121 | .long 0 /* microcode base */ |
| 122 | .long 0 /* microcode size */ |
Bin Meng | 08e484c | 2014-12-17 15:50:36 +0800 | [diff] [blame] | 123 | .long CONFIG_SYS_MONITOR_BASE /* code region base */ |
| 124 | .long CONFIG_SYS_MONITOR_LEN /* code region size */ |