fsp_car.S 3.2 KB

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