Tom Rini | 83d290c | 2018-05-06 17:58:06 -0400 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
Bin Meng | b2e02d2 | 2014-12-17 15:50:36 +0800 | [diff] [blame] | 2 | /* |
| 3 | * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> |
Bin Meng | b2e02d2 | 2014-12-17 15:50:36 +0800 | [diff] [blame] | 4 | */ |
| 5 | |
| 6 | #include <config.h> |
| 7 | #include <asm/post.h> |
| 8 | |
| 9 | .globl car_init |
| 10 | car_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 | |
| 21 | car_init_start: |
| 22 | post_code(POST_CAR_START) |
Simon Glass | e2adc36 | 2019-09-25 08:11:25 -0600 | [diff] [blame^] | 23 | lea fsp_find_header_romstack, %esp |
| 24 | jmp fsp_find_header |
Bin Meng | b2e02d2 | 2014-12-17 15:50:36 +0800 | [diff] [blame] | 25 | |
Simon Glass | e2adc36 | 2019-09-25 08:11:25 -0600 | [diff] [blame^] | 26 | fsp_find_header_ret: |
Bin Meng | b2e02d2 | 2014-12-17 15:50:36 +0800 | [diff] [blame] | 27 | /* EAX points to FSP_INFO_HEADER */ |
| 28 | mov %eax, %ebp |
| 29 | |
| 30 | /* sanity test */ |
Bin Meng | 8c5224c | 2014-12-17 15:50:42 +0800 | [diff] [blame] | 31 | cmp $CONFIG_FSP_ADDR, %eax |
Bin Meng | b2e02d2 | 2014-12-17 15:50:36 +0800 | [diff] [blame] | 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 | |
| 42 | temp_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 |
Bin Meng | aefaff8 | 2015-06-07 11:33:14 +0800 | [diff] [blame] | 58 | subl $4, %esp |
Bin Meng | b2e02d2 | 2014-12-17 15:50:36 +0800 | [diff] [blame] | 59 | |
Bin Meng | aefaff8 | 2015-06-07 11:33:14 +0800 | [diff] [blame] | 60 | xor %esi, %esi |
| 61 | jmp car_init_done |
Bin Meng | b2e02d2 | 2014-12-17 15:50:36 +0800 | [diff] [blame] | 62 | |
| 63 | .global fsp_init_done |
| 64 | fsp_init_done: |
| 65 | /* |
Bin Meng | 48aa6c2 | 2015-08-20 06:40:20 -0700 | [diff] [blame] | 66 | * We come here from fsp_continue() with eax pointing to the HOB list. |
Bin Meng | b2e02d2 | 2014-12-17 15:50:36 +0800 | [diff] [blame] | 67 | * Save eax to esi temporarily. |
| 68 | */ |
| 69 | movl %eax, %esi |
Bin Meng | aefaff8 | 2015-06-07 11:33:14 +0800 | [diff] [blame] | 70 | |
| 71 | car_init_done: |
Bin Meng | b2e02d2 | 2014-12-17 15:50:36 +0800 | [diff] [blame] | 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 | |
| 79 | car_init_fail: |
| 80 | post_code(POST_CAR_FAILURE) |
| 81 | |
| 82 | die: |
| 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 |
Simon Glass | e2adc36 | 2019-09-25 08:11:25 -0600 | [diff] [blame^] | 94 | fsp_find_header_romstack: |
| 95 | .long fsp_find_header_ret |
Bin Meng | b2e02d2 | 2014-12-17 15:50:36 +0800 | [diff] [blame] | 96 | |
| 97 | .balign 4 |
| 98 | temp_ram_init_romstack: |
| 99 | .long temp_ram_init_ret |
| 100 | .long temp_ram_init_params |
| 101 | temp_ram_init_params: |
Simon Glass | 0f61de8 | 2014-12-17 15:50:37 +0800 | [diff] [blame] | 102 | _dt_ucode_base_size: |
Simon Glass | 11b7cc3 | 2019-04-25 21:58:44 -0600 | [diff] [blame] | 103 | /* These next two fields are filled in by binman */ |
Simon Glass | e77b62e | 2016-03-11 22:07:11 -0700 | [diff] [blame] | 104 | .globl ucode_base |
Ivan Gorinov | 8199a14 | 2018-06-21 21:16:16 -0700 | [diff] [blame] | 105 | ucode_base: /* Declared in microcode.h */ |
Simon Glass | 0f61de8 | 2014-12-17 15:50:37 +0800 | [diff] [blame] | 106 | .long 0 /* microcode base */ |
Ivan Gorinov | 8199a14 | 2018-06-21 21:16:16 -0700 | [diff] [blame] | 107 | .globl ucode_size |
| 108 | ucode_size: /* Declared in microcode.h */ |
Simon Glass | 0f61de8 | 2014-12-17 15:50:37 +0800 | [diff] [blame] | 109 | .long 0 /* microcode size */ |
Bin Meng | b2e02d2 | 2014-12-17 15:50:36 +0800 | [diff] [blame] | 110 | .long CONFIG_SYS_MONITOR_BASE /* code region base */ |
| 111 | .long CONFIG_SYS_MONITOR_LEN /* code region size */ |