fconf_sec_intr_config.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <assert.h>
  7. #include <common/debug.h>
  8. #include <common/fdt_wrappers.h>
  9. #include <libfdt.h>
  10. #include <plat/arm/common/fconf_sec_intr_config.h>
  11. #define G0_INTR_NUM(i) g0_intr_prop[3U * (i)]
  12. #define G0_INTR_PRIORITY(i) g0_intr_prop[3U * (i) + 1]
  13. #define G0_INTR_CONFIG(i) g0_intr_prop[3U * (i) + 2]
  14. #define G1S_INTR_NUM(i) g1s_intr_prop[3U * (i)]
  15. #define G1S_INTR_PRIORITY(i) g1s_intr_prop[3U * (i) + 1]
  16. #define G1S_INTR_CONFIG(i) g1s_intr_prop[3U * (i) + 2]
  17. struct sec_intr_prop_t sec_intr_prop;
  18. static void print_intr_prop(interrupt_prop_t prop)
  19. {
  20. VERBOSE("FCONF: Secure Interrupt NUM: %d, PRI: %d, TYPE: %d\n",
  21. prop.intr_num, prop.intr_pri, prop.intr_cfg);
  22. }
  23. int fconf_populate_sec_intr_config(uintptr_t config)
  24. {
  25. int node, err;
  26. uint32_t g0_intr_count, g1s_intr_count;
  27. uint32_t g0_intr_prop[SEC_INT_COUNT_MAX * 3];
  28. uint32_t g1s_intr_prop[SEC_INT_COUNT_MAX * 3];
  29. /* Necessary to work with libfdt APIs */
  30. const void *hw_config_dtb = (const void *)config;
  31. node = fdt_node_offset_by_compatible(hw_config_dtb, -1,
  32. "arm,secure_interrupt_desc");
  33. if (node < 0) {
  34. ERROR("FCONF: Unable to locate node with %s compatible property\n",
  35. "arm,secure_interrupt_desc");
  36. return node;
  37. }
  38. /* Read number of Group 0 interrupts specified by platform */
  39. err = fdt_read_uint32(hw_config_dtb, node, "g0_intr_cnt", &g0_intr_count);
  40. if (err < 0) {
  41. ERROR("FCONF: Could not locate g0s_intr_cnt property\n");
  42. return err;
  43. }
  44. /* At least 1 Group 0 interrupt description has to be provided*/
  45. if (g0_intr_count < 1U) {
  46. ERROR("FCONF: Invalid number of Group 0 interrupts count specified\n");
  47. return -1;
  48. }
  49. /* Read number of Group 1 secure interrupts specified by platform */
  50. err = fdt_read_uint32(hw_config_dtb, node, "g1s_intr_cnt",
  51. &g1s_intr_count);
  52. if (err < 0) {
  53. ERROR("FCONF: Could not locate g1s_intr_cnt property\n");
  54. return err;
  55. }
  56. /* At least one Group 1 interrupt description has to be provided*/
  57. if (g1s_intr_count < 1U) {
  58. ERROR("FCONF: Invalid number of Group 1 secure interrupts count specified\n");
  59. return -1;
  60. }
  61. /*
  62. * Check if the total number of secure interrupts described are within
  63. * the limit defined statically by the platform.
  64. */
  65. if ((g0_intr_count + g1s_intr_count) > SEC_INT_COUNT_MAX) {
  66. ERROR("FCONF: Total number of secure interrupts exceed limit the of %d\n",
  67. SEC_INT_COUNT_MAX);
  68. return -1;
  69. }
  70. sec_intr_prop.count = g0_intr_count + g1s_intr_count;
  71. /* Read the Group 0 interrupt descriptors */
  72. err = fdt_read_uint32_array(hw_config_dtb, node, "g0_intr_desc",
  73. g0_intr_count * 3, g0_intr_prop);
  74. if (err < 0) {
  75. ERROR("FCONF: Read cell failed for 'g0s_intr_desc': %d\n", err);
  76. return err;
  77. }
  78. /* Read the Group 1 secure interrupt descriptors */
  79. err = fdt_read_uint32_array(hw_config_dtb, node, "g1s_intr_desc",
  80. g1s_intr_count * 3, g1s_intr_prop);
  81. if (err < 0) {
  82. ERROR("FCONF: Read cell failed for 'g1s_intr_desc': %d\n", err);
  83. return err;
  84. }
  85. /* Populate Group 0 interrupt descriptors into fconf based C struct */
  86. for (uint32_t i = 0; i < g0_intr_count; i++) {
  87. interrupt_prop_t sec_intr_property;
  88. /* Secure Interrupt Group: INTR_GROUP0 i.e., 0x1 */
  89. sec_intr_property.intr_grp = 1;
  90. sec_intr_property.intr_num = G0_INTR_NUM(i);
  91. sec_intr_property.intr_pri = G0_INTR_PRIORITY(i);
  92. sec_intr_property.intr_cfg = G0_INTR_CONFIG(i);
  93. sec_intr_prop.descriptor[i] = sec_intr_property;
  94. print_intr_prop(sec_intr_property);
  95. }
  96. /* Populate G1 secure interrupt descriptors into fconf based C struct */
  97. for (uint32_t i = 0; i < g1s_intr_count; i++) {
  98. interrupt_prop_t sec_intr_property;
  99. /* Secure Interrupt Group: INTR_GROUP1S i.e., 0x0 */
  100. sec_intr_property.intr_grp = 0;
  101. sec_intr_property.intr_num = G1S_INTR_NUM(i);
  102. sec_intr_property.intr_pri = G1S_INTR_PRIORITY(i);
  103. sec_intr_property.intr_cfg = G1S_INTR_CONFIG(i);
  104. sec_intr_prop.descriptor[i + g0_intr_count] = sec_intr_property;
  105. print_intr_prop(sec_intr_property);
  106. }
  107. return 0;
  108. }
  109. FCONF_REGISTER_POPULATOR(HW_CONFIG, sec_intr_prop, fconf_populate_sec_intr_config);