sbi_init.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /*
  2. * SPDX-License-Identifier: BSD-2-Clause
  3. *
  4. * Copyright (c) 2019 Western Digital Corporation or its affiliates.
  5. *
  6. * Authors:
  7. * Anup Patel <anup.patel@wdc.com>
  8. */
  9. #include <sbi/riscv_asm.h>
  10. #include <sbi/riscv_atomic.h>
  11. #include <sbi/sbi_console.h>
  12. #include <sbi/sbi_ecall.h>
  13. #include <sbi/sbi_hart.h>
  14. #include <sbi/sbi_ipi.h>
  15. #include <sbi/sbi_platform.h>
  16. #include <sbi/sbi_system.h>
  17. #include <sbi/sbi_timer.h>
  18. #include <sbi/sbi_version.h>
  19. #define BANNER \
  20. " ____ _____ ____ _____\n" \
  21. " / __ \\ / ____| _ \\_ _|\n" \
  22. " | | | |_ __ ___ _ __ | (___ | |_) || |\n" \
  23. " | | | | '_ \\ / _ \\ '_ \\ \\___ \\| _ < | |\n" \
  24. " | |__| | |_) | __/ | | |____) | |_) || |_\n" \
  25. " \\____/| .__/ \\___|_| |_|_____/|____/_____|\n" \
  26. " | |\n" \
  27. " |_|\n\n"
  28. static void sbi_boot_prints(struct sbi_scratch *scratch, u32 hartid)
  29. {
  30. char str[64];
  31. const struct sbi_platform *plat = sbi_platform_ptr(scratch);
  32. misa_string(str, sizeof(str));
  33. sbi_printf("\nOpenSBI v%d.%d (%s %s)\n",
  34. OPENSBI_VERSION_MAJOR, OPENSBI_VERSION_MINOR,
  35. __DATE__, __TIME__);
  36. sbi_printf(BANNER);
  37. /* Platform details */
  38. sbi_printf("Platform Name : %s\n", sbi_platform_name(plat));
  39. sbi_printf("Platform HART Features : RV%d%s\n", misa_xlen(), str);
  40. sbi_printf("Platform Max HARTs : %d\n",
  41. sbi_platform_hart_count(plat));
  42. sbi_printf("Current Hart : %u\n", hartid);
  43. /* Firmware details */
  44. sbi_printf("Firmware Base : 0x%lx\n", scratch->fw_start);
  45. sbi_printf("Firmware Size : %d KB\n",
  46. (u32)(scratch->fw_size / 1024));
  47. /* Generic details */
  48. sbi_printf("Runtime SBI Version : %d.%d\n",
  49. sbi_ecall_version_major(), sbi_ecall_version_minor());
  50. sbi_printf("\n");
  51. sbi_hart_pmp_dump(scratch);
  52. }
  53. static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
  54. {
  55. int rc;
  56. const struct sbi_platform *plat = sbi_platform_ptr(scratch);
  57. rc = sbi_system_early_init(scratch, TRUE);
  58. if (rc)
  59. sbi_hart_hang();
  60. rc = sbi_hart_init(scratch, hartid);
  61. if (rc)
  62. sbi_hart_hang();
  63. rc = sbi_console_init(scratch);
  64. if (rc)
  65. sbi_hart_hang();
  66. rc = sbi_platform_irqchip_init(plat, TRUE);
  67. if (rc)
  68. sbi_hart_hang();
  69. rc = sbi_ipi_init(scratch, TRUE);
  70. if (rc)
  71. sbi_hart_hang();
  72. rc = sbi_timer_init(scratch, TRUE);
  73. if (rc)
  74. sbi_hart_hang();
  75. rc = sbi_system_final_init(scratch, TRUE);
  76. if (rc)
  77. sbi_hart_hang();
  78. if (!(scratch->options & SBI_SCRATCH_NO_BOOT_PRINTS))
  79. sbi_boot_prints(scratch, hartid);
  80. if (!sbi_platform_has_hart_hotplug(plat))
  81. sbi_hart_wake_coldboot_harts(scratch, hartid);
  82. sbi_hart_mark_available(hartid);
  83. sbi_hart_switch_mode(hartid, scratch->next_arg1,
  84. scratch->next_addr, scratch->next_mode);
  85. }
  86. static void __noreturn init_warmboot(struct sbi_scratch *scratch, u32 hartid)
  87. {
  88. int rc;
  89. const struct sbi_platform *plat = sbi_platform_ptr(scratch);
  90. if (!sbi_platform_has_hart_hotplug(plat))
  91. sbi_hart_wait_for_coldboot(scratch, hartid);
  92. if (sbi_platform_hart_disabled(plat, hartid))
  93. sbi_hart_hang();
  94. rc = sbi_system_early_init(scratch, FALSE);
  95. if (rc)
  96. sbi_hart_hang();
  97. rc = sbi_hart_init(scratch, hartid);
  98. if (rc)
  99. sbi_hart_hang();
  100. rc = sbi_platform_irqchip_init(plat, FALSE);
  101. if (rc)
  102. sbi_hart_hang();
  103. rc = sbi_ipi_init(scratch, FALSE);
  104. if (rc)
  105. sbi_hart_hang();
  106. rc = sbi_timer_init(scratch, FALSE);
  107. if (rc)
  108. sbi_hart_hang();
  109. rc = sbi_system_final_init(scratch, FALSE);
  110. if (rc)
  111. sbi_hart_hang();
  112. sbi_hart_mark_available(hartid);
  113. if (sbi_platform_has_hart_hotplug(plat))
  114. /* TODO: To be implemented in-future. */
  115. sbi_hart_hang();
  116. else
  117. sbi_hart_switch_mode(hartid, scratch->next_arg1,
  118. scratch->next_addr, scratch->next_mode);
  119. }
  120. static atomic_t coldboot_lottery = ATOMIC_INITIALIZER(0);
  121. /**
  122. * Initialize OpenSBI library for current HART and jump to next
  123. * booting stage.
  124. *
  125. * The function expects following:
  126. * 1. The 'mscratch' CSR is pointing to sbi_scratch of current HART
  127. * 2. Stack pointer (SP) is setup for current HART
  128. * 3. Interrupts are disabled in MSTATUS CSR
  129. * 4. All interrupts are disabled in MIE CSR
  130. *
  131. * @param scratch pointer to sbi_scratch of current HART
  132. */
  133. void __noreturn sbi_init(struct sbi_scratch *scratch)
  134. {
  135. bool coldboot = FALSE;
  136. u32 hartid = sbi_current_hartid();
  137. const struct sbi_platform *plat = sbi_platform_ptr(scratch);
  138. if (sbi_platform_hart_disabled(plat, hartid))
  139. sbi_hart_hang();
  140. if (atomic_add_return(&coldboot_lottery, 1) == 1)
  141. coldboot = TRUE;
  142. if (coldboot)
  143. init_coldboot(scratch, hartid);
  144. else
  145. init_warmboot(scratch, hartid);
  146. }