platform.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. * SPDX-License-Identifier: BSD-2-Clause
  3. *
  4. * Copyright (c) 2019 Andes Technology Corporation
  5. *
  6. * Authors:
  7. * Zong Li <zong@andestech.com>
  8. * Nylon Chen <nylon7@andestech.com>
  9. */
  10. #include <sbi/riscv_asm.h>
  11. #include <sbi/riscv_encoding.h>
  12. #include <sbi/sbi_console.h>
  13. #include <sbi/sbi_const.h>
  14. #include <sbi/sbi_ipi.h>
  15. #include <sbi/sbi_platform.h>
  16. #include <sbi/sbi_trap.h>
  17. #include <sbi_utils/fdt/fdt_helper.h>
  18. #include <sbi_utils/fdt/fdt_fixup.h>
  19. #include <sbi_utils/irqchip/plic.h>
  20. #include <sbi_utils/serial/fdt_serial.h>
  21. #include <sbi_utils/timer/fdt_timer.h>
  22. #include "platform.h"
  23. #include "plicsw.h"
  24. #include "cache.h"
  25. static struct plic_data plic = {
  26. .addr = AE350_PLIC_ADDR,
  27. .num_src = AE350_PLIC_NUM_SOURCES,
  28. };
  29. /* Platform final initialization. */
  30. static int ae350_final_init(bool cold_boot)
  31. {
  32. void *fdt;
  33. if (!cold_boot)
  34. return 0;
  35. fdt = fdt_get_address();
  36. fdt_fixups(fdt);
  37. return 0;
  38. }
  39. /* Initialize the platform interrupt controller for current HART. */
  40. static int ae350_irqchip_init(bool cold_boot)
  41. {
  42. u32 hartid = current_hartid();
  43. int ret;
  44. if (cold_boot) {
  45. ret = plic_cold_irqchip_init(&plic);
  46. if (ret)
  47. return ret;
  48. }
  49. return plic_warm_irqchip_init(&plic, 2 * hartid, 2 * hartid + 1);
  50. }
  51. static struct sbi_ipi_device plicsw_ipi = {
  52. .name = "ae350_plicsw",
  53. .ipi_send = plicsw_ipi_send,
  54. .ipi_clear = plicsw_ipi_clear
  55. };
  56. /* Initialize IPI for current HART. */
  57. static int ae350_ipi_init(bool cold_boot)
  58. {
  59. int ret;
  60. if (cold_boot) {
  61. ret = plicsw_cold_ipi_init(AE350_PLICSW_ADDR,
  62. AE350_HART_COUNT);
  63. if (ret)
  64. return ret;
  65. sbi_ipi_set_device(&plicsw_ipi);
  66. }
  67. return plicsw_warm_ipi_init();
  68. }
  69. /* Vendor-Specific SBI handler */
  70. static int ae350_vendor_ext_provider(long extid, long funcid,
  71. const struct sbi_trap_regs *regs, unsigned long *out_value,
  72. struct sbi_trap_info *out_trap)
  73. {
  74. int ret = 0;
  75. switch (funcid) {
  76. case SBI_EXT_ANDES_GET_MCACHE_CTL_STATUS:
  77. *out_value = csr_read(CSR_MCACHECTL);
  78. break;
  79. case SBI_EXT_ANDES_GET_MMISC_CTL_STATUS:
  80. *out_value = csr_read(CSR_MMISCCTL);
  81. break;
  82. case SBI_EXT_ANDES_SET_MCACHE_CTL:
  83. ret = mcall_set_mcache_ctl(regs->a0);
  84. break;
  85. case SBI_EXT_ANDES_SET_MMISC_CTL:
  86. ret = mcall_set_mmisc_ctl(regs->a0);
  87. break;
  88. case SBI_EXT_ANDES_ICACHE_OP:
  89. ret = mcall_icache_op(regs->a0);
  90. break;
  91. case SBI_EXT_ANDES_DCACHE_OP:
  92. ret = mcall_dcache_op(regs->a0);
  93. break;
  94. case SBI_EXT_ANDES_L1CACHE_I_PREFETCH:
  95. ret = mcall_l1_cache_i_prefetch_op(regs->a0);
  96. break;
  97. case SBI_EXT_ANDES_L1CACHE_D_PREFETCH:
  98. ret = mcall_l1_cache_d_prefetch_op(regs->a0);
  99. break;
  100. case SBI_EXT_ANDES_NON_BLOCKING_LOAD_STORE:
  101. ret = mcall_non_blocking_load_store(regs->a0);
  102. break;
  103. case SBI_EXT_ANDES_WRITE_AROUND:
  104. ret = mcall_write_around(regs->a0);
  105. break;
  106. default:
  107. sbi_printf("Unsupported vendor sbi call : %ld\n", funcid);
  108. asm volatile("ebreak");
  109. }
  110. return ret;
  111. }
  112. /* Platform descriptor. */
  113. const struct sbi_platform_operations platform_ops = {
  114. .final_init = ae350_final_init,
  115. .console_init = fdt_serial_init,
  116. .irqchip_init = ae350_irqchip_init,
  117. .ipi_init = ae350_ipi_init,
  118. .timer_init = fdt_timer_init,
  119. .vendor_ext_provider = ae350_vendor_ext_provider
  120. };
  121. const struct sbi_platform platform = {
  122. .opensbi_version = OPENSBI_VERSION,
  123. .platform_version =
  124. SBI_PLATFORM_VERSION(CONFIG_PLATFORM_ANDES_AE350_MAJOR_VER,
  125. CONFIG_PLATFORM_ANDES_AE350_MINOR_VER),
  126. .name = CONFIG_PLATFORM_ANDES_AE350_NAME,
  127. .features = SBI_PLATFORM_DEFAULT_FEATURES,
  128. .hart_count = AE350_HART_COUNT,
  129. .hart_stack_size = SBI_PLATFORM_DEFAULT_HART_STACK_SIZE,
  130. .platform_ops_addr = (unsigned long)&platform_ops
  131. };