sunxi_bl31_setup.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /*
  2. * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <assert.h>
  7. #include <libfdt.h>
  8. #include <platform_def.h>
  9. #include <arch.h>
  10. #include <arch_helpers.h>
  11. #include <common/debug.h>
  12. #include <common/fdt_fixup.h>
  13. #include <drivers/arm/gicv2.h>
  14. #include <drivers/console.h>
  15. #include <drivers/generic_delay_timer.h>
  16. #include <drivers/ti/uart/uart_16550.h>
  17. #include <lib/mmio.h>
  18. #include <plat/common/platform.h>
  19. #include <sunxi_def.h>
  20. #include <sunxi_mmap.h>
  21. #include <sunxi_private.h>
  22. static entry_point_info_t bl32_image_ep_info;
  23. static entry_point_info_t bl33_image_ep_info;
  24. static console_t console;
  25. static void *fdt;
  26. static const gicv2_driver_data_t sunxi_gic_data = {
  27. .gicd_base = SUNXI_GICD_BASE,
  28. .gicc_base = SUNXI_GICC_BASE,
  29. };
  30. /*
  31. * Try to find a DTB loaded in memory by previous stages.
  32. *
  33. * At the moment we implement a heuristic to find the DTB attached to U-Boot:
  34. * U-Boot appends its DTB to the end of the image. Assuming that BL33 is
  35. * U-Boot, try to find the size of the U-Boot image to learn the DTB address.
  36. * The generic ARMv8 U-Boot image contains the load address and its size
  37. * as u64 variables at the beginning of the image. There might be padding
  38. * or other headers before that data, so scan the first 2KB after the BL33
  39. * entry point to find the load address, which should be followed by the
  40. * size. Adding those together gives us the address of the DTB.
  41. */
  42. static void sunxi_find_dtb(void)
  43. {
  44. uint64_t *u_boot_base;
  45. int i;
  46. u_boot_base = (void *)SUNXI_BL33_VIRT_BASE;
  47. for (i = 0; i < 2048 / sizeof(uint64_t); i++) {
  48. void *dtb_base;
  49. if (u_boot_base[i] != PRELOADED_BL33_BASE)
  50. continue;
  51. /* Does the suspected U-Boot size look anyhow reasonable? */
  52. if (u_boot_base[i + 1] >= 256 * 1024 * 1024)
  53. continue;
  54. /* end of the image: base address + size */
  55. dtb_base = (char *)u_boot_base + u_boot_base[i + 1];
  56. if (fdt_check_header(dtb_base) == 0) {
  57. fdt = dtb_base;
  58. return;
  59. }
  60. }
  61. }
  62. void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
  63. u_register_t arg2, u_register_t arg3)
  64. {
  65. /* Initialize the debug console as soon as possible */
  66. console_16550_register(SUNXI_UART0_BASE, SUNXI_UART0_CLK_IN_HZ,
  67. SUNXI_UART0_BAUDRATE, &console);
  68. #ifdef BL32_BASE
  69. /* Populate entry point information for BL32 */
  70. SET_PARAM_HEAD(&bl32_image_ep_info, PARAM_EP, VERSION_1, 0);
  71. SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
  72. bl32_image_ep_info.pc = BL32_BASE;
  73. #endif
  74. /* Populate entry point information for BL33 */
  75. SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0);
  76. /*
  77. * Tell BL31 where the non-trusted software image
  78. * is located and the entry state information
  79. */
  80. bl33_image_ep_info.pc = PRELOADED_BL33_BASE;
  81. bl33_image_ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
  82. DISABLE_ALL_EXCEPTIONS);
  83. SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
  84. }
  85. void bl31_plat_arch_setup(void)
  86. {
  87. sunxi_configure_mmu_el3(0);
  88. }
  89. void bl31_platform_setup(void)
  90. {
  91. const char *soc_name;
  92. uint16_t soc_id = sunxi_read_soc_id();
  93. switch (soc_id) {
  94. case SUNXI_SOC_A64:
  95. soc_name = "A64/H64/R18";
  96. break;
  97. case SUNXI_SOC_H5:
  98. soc_name = "H5";
  99. break;
  100. case SUNXI_SOC_H6:
  101. soc_name = "H6";
  102. break;
  103. case SUNXI_SOC_H616:
  104. soc_name = "H616";
  105. break;
  106. case SUNXI_SOC_R329:
  107. soc_name = "R329";
  108. break;
  109. default:
  110. soc_name = "unknown";
  111. break;
  112. }
  113. NOTICE("BL31: Detected Allwinner %s SoC (%04x)\n", soc_name, soc_id);
  114. generic_delay_timer_init();
  115. sunxi_find_dtb();
  116. if (fdt) {
  117. const char *model;
  118. int length;
  119. model = fdt_getprop(fdt, 0, "model", &length);
  120. NOTICE("BL31: Found U-Boot DTB at %p, model: %s\n", fdt,
  121. model ?: "unknown");
  122. } else {
  123. NOTICE("BL31: No DTB found.\n");
  124. }
  125. /* Configure the interrupt controller */
  126. gicv2_driver_init(&sunxi_gic_data);
  127. gicv2_distif_init();
  128. gicv2_pcpu_distif_init();
  129. gicv2_cpuif_enable();
  130. sunxi_security_setup();
  131. /*
  132. * On the A64 U-Boot's SPL sets the bus clocks to some conservative
  133. * values, to work around FEL mode instabilities with SRAM C accesses.
  134. * FEL mode is gone when we reach ATF, so bring the AHB1 bus
  135. * (the "main" bus) clock frequency back to the recommended 200MHz,
  136. * for improved performance.
  137. */
  138. if (soc_id == SUNXI_SOC_A64)
  139. mmio_write_32(SUNXI_CCU_BASE + 0x54, 0x00003180);
  140. /*
  141. * U-Boot or the kernel don't setup AHB2, which leaves it at the
  142. * AHB1 frequency (200 MHz, see above). However Allwinner recommends
  143. * 300 MHz, for improved Ethernet and USB performance. Switch the
  144. * clock to use "PLL_PERIPH0 / 2".
  145. */
  146. if (soc_id == SUNXI_SOC_A64 || soc_id == SUNXI_SOC_H5)
  147. mmio_write_32(SUNXI_CCU_BASE + 0x5c, 0x1);
  148. sunxi_pmic_setup(soc_id, fdt);
  149. INFO("BL31: Platform setup done\n");
  150. }
  151. void bl31_plat_runtime_setup(void)
  152. {
  153. /* Change the DTB if the configuration requires so. */
  154. sunxi_prepare_dtb(fdt);
  155. }
  156. entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
  157. {
  158. assert(sec_state_is_valid(type) != 0);
  159. if (type == NON_SECURE)
  160. return &bl33_image_ep_info;
  161. if ((type == SECURE) && bl32_image_ep_info.pc)
  162. return &bl32_image_ep_info;
  163. return NULL;
  164. }