fpga_gicv3.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <common/debug.h>
  7. #include <common/fdt_wrappers.h>
  8. #include <drivers/arm/arm_gicv3_common.h>
  9. #include <drivers/arm/gic_common.h>
  10. #include <drivers/arm/gicv3.h>
  11. #include <lib/mmio.h>
  12. #include <libfdt.h>
  13. #include <platform_def.h>
  14. #include <plat/common/platform.h>
  15. #include <platform_def.h>
  16. static const interrupt_prop_t fpga_interrupt_props[] = {
  17. PLATFORM_G1S_PROPS(INTR_GROUP1S),
  18. PLATFORM_G0_PROPS(INTR_GROUP0)
  19. };
  20. static uintptr_t fpga_rdistif_base_addrs[PLATFORM_CORE_COUNT];
  21. static int nr_itses;
  22. static unsigned int fpga_mpidr_to_core_pos(unsigned long mpidr)
  23. {
  24. return (unsigned int)plat_core_pos_by_mpidr(mpidr);
  25. }
  26. static gicv3_driver_data_t fpga_gicv3_driver_data = {
  27. .interrupt_props = fpga_interrupt_props,
  28. .interrupt_props_num = ARRAY_SIZE(fpga_interrupt_props),
  29. .rdistif_num = PLATFORM_CORE_COUNT,
  30. .rdistif_base_addrs = fpga_rdistif_base_addrs,
  31. .mpidr_to_core_pos = fpga_mpidr_to_core_pos
  32. };
  33. void plat_fpga_gic_init(void)
  34. {
  35. const void *fdt = (void *)(uintptr_t)FPGA_PRELOADED_DTB_BASE;
  36. uintptr_t gicr_base = 0U;
  37. uint32_t iidr;
  38. int node, ret;
  39. node = fdt_node_offset_by_compatible(fdt, 0, "arm,gic-v3");
  40. if (node < 0) {
  41. WARN("No \"arm,gic-v3\" compatible node found in DT, no GIC support.\n");
  42. return;
  43. }
  44. /* TODO: Assuming only empty "ranges;" properties up the bus path. */
  45. ret = fdt_get_reg_props_by_index(fdt, node, 0,
  46. &fpga_gicv3_driver_data.gicd_base, NULL);
  47. if (ret < 0) {
  48. WARN("Could not read GIC distributor address from DT.\n");
  49. return;
  50. }
  51. iidr = mmio_read_32(fpga_gicv3_driver_data.gicd_base + GICD_IIDR);
  52. if (((iidr & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_600) ||
  53. ((iidr & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_700)) {
  54. unsigned int frame_id;
  55. /*
  56. * According to the GIC TRMs, if there are any ITSes, they
  57. * start four 64K pages after the distributor. After all
  58. * the ITSes then follow the redistributors.
  59. */
  60. gicr_base = fpga_gicv3_driver_data.gicd_base + (4U << 16);
  61. do {
  62. uint64_t its_typer;
  63. /* Each GIC component can be identified by its ID. */
  64. frame_id = gicv3_get_component_partnum(gicr_base);
  65. if (frame_id == PIDR_COMPONENT_ARM_REDIST) {
  66. INFO("Found %d ITSes, redistributors start at 0x%llx\n",
  67. nr_itses, (unsigned long long)gicr_base);
  68. break;
  69. }
  70. if (frame_id != PIDR_COMPONENT_ARM_ITS) {
  71. WARN("GICv3: found unexpected frame 0x%x\n",
  72. frame_id);
  73. gicr_base = 0U;
  74. break;
  75. }
  76. /*
  77. * Found an ITS, now work out if it supports virtual
  78. * SGIs (for direct guest injection). If yes, each
  79. * ITS occupies four 64K pages, otherwise just two.
  80. */
  81. its_typer = mmio_read_64(gicr_base + GITS_TYPER);
  82. if ((its_typer & GITS_TYPER_VSGI) != 0U) {
  83. gicr_base += 4U << 16;
  84. } else {
  85. gicr_base += 2U << 16;
  86. }
  87. nr_itses++;
  88. } while (true);
  89. }
  90. /*
  91. * If this is not a GIC-600 or -700, or the autodetection above failed,
  92. * use the base address from the device tree.
  93. */
  94. if (gicr_base == 0U) {
  95. ret = fdt_get_reg_props_by_index(fdt, node, 1,
  96. &fpga_gicv3_driver_data.gicr_base,
  97. NULL);
  98. if (ret < 0) {
  99. WARN("Could not read GIC redistributor address from DT.\n");
  100. return;
  101. }
  102. } else {
  103. fpga_gicv3_driver_data.gicr_base = gicr_base;
  104. }
  105. gicv3_driver_init(&fpga_gicv3_driver_data);
  106. gicv3_distif_init();
  107. gicv3_rdistif_init(plat_my_core_pos());
  108. gicv3_cpuif_enable(plat_my_core_pos());
  109. }
  110. void fpga_pwr_gic_on_finish(void)
  111. {
  112. gicv3_rdistif_init(plat_my_core_pos());
  113. gicv3_cpuif_enable(plat_my_core_pos());
  114. }
  115. void fpga_pwr_gic_off(void)
  116. {
  117. gicv3_cpuif_disable(plat_my_core_pos());
  118. gicv3_rdistif_off(plat_my_core_pos());
  119. }
  120. unsigned int fpga_get_nr_gic_cores(void)
  121. {
  122. return gicv3_rdistif_get_number_frames(fpga_gicv3_driver_data.gicr_base);
  123. }
  124. uintptr_t fpga_get_redist_size(void)
  125. {
  126. uint64_t typer_val = mmio_read_64(fpga_gicv3_driver_data.gicr_base +
  127. GICR_TYPER);
  128. return gicv3_redist_size(typer_val);
  129. }
  130. uintptr_t fpga_get_redist_base(void)
  131. {
  132. return fpga_gicv3_driver_data.gicr_base;
  133. }
  134. bool fpga_has_its(void)
  135. {
  136. return nr_itses > 0;
  137. }