plat_secondary.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /*
  2. * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <assert.h>
  7. #include <string.h>
  8. #include <arch_helpers.h>
  9. #include <common/debug.h>
  10. #include <lib/mmio.h>
  11. #include <mce.h>
  12. #include <tegra194_private.h>
  13. #include <tegra_def.h>
  14. #include <tegra_private.h>
  15. extern uint64_t tegra_bl31_phys_base;
  16. #define MISCREG_AA64_RST_LOW 0x2004U
  17. #define MISCREG_AA64_RST_HIGH 0x2008U
  18. #define CPU_RESET_MODE_AA64 1U
  19. /*******************************************************************************
  20. * Setup secondary CPU vectors
  21. ******************************************************************************/
  22. void plat_secondary_setup(void)
  23. {
  24. uint32_t addr_low, addr_high;
  25. plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
  26. uint64_t cpu_reset_handler_base, cpu_reset_handler_size, tzdram_addr;
  27. uint64_t src_len_bytes = BL_END - tegra_bl31_phys_base;
  28. INFO("Setting up secondary CPU boot\n");
  29. tzdram_addr = params_from_bl2->tzdram_base +
  30. tegra194_get_cpu_reset_handler_size();
  31. /*
  32. * The BL31 code resides in the TZSRAM which loses state
  33. * when we enter System Suspend. Copy the wakeup trampoline
  34. * code to TZDRAM to help us exit from System Suspend.
  35. */
  36. cpu_reset_handler_base = tegra194_get_cpu_reset_handler_base();
  37. cpu_reset_handler_size = tegra194_get_cpu_reset_handler_size();
  38. memcpy((void *)((uintptr_t)params_from_bl2->tzdram_base),
  39. (void *)((uintptr_t)cpu_reset_handler_base),
  40. cpu_reset_handler_size);
  41. /* TZDRAM base will be used as the "resume" address */
  42. addr_low = (uint32_t)params_from_bl2->tzdram_base | CPU_RESET_MODE_AA64;
  43. addr_high = (uint32_t)((params_from_bl2->tzdram_base >> 32U) & 0x7ffU);
  44. /* write lower 32 bits first, then the upper 11 bits */
  45. mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_LOW, addr_low);
  46. assert(mmio_read_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_LOW) == addr_low);
  47. mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_HIGH, addr_high);
  48. assert(mmio_read_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_HIGH) == addr_high);
  49. /* save reset vector to be used during SYSTEM_SUSPEND exit */
  50. mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_LO,
  51. addr_low);
  52. assert(mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_LO) == addr_low);
  53. mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_HI,
  54. addr_high);
  55. assert(mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_HI) == addr_high);
  56. mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV72_LO,
  57. (uint32_t)tzdram_addr);
  58. assert(mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV72_LO) == (uint32_t)tzdram_addr);
  59. mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV72_HI,
  60. (uint32_t)src_len_bytes);
  61. assert(mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV72_HI) == (uint32_t)src_len_bytes);
  62. }