cpu_spin_table.c 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. */
  9. #include <rthw.h>
  10. #include <rtthread.h>
  11. #include "cpu.h"
  12. #ifdef RT_USING_SMART
  13. #include <ioremap.h>
  14. #else
  15. #define rt_ioremap(x, ...) (x)
  16. #define rt_iounmap(x)
  17. #endif
  18. #define DBG_TAG "libcpu.aarch64.cpu_spin_table"
  19. #define DBG_LVL DBG_INFO
  20. #include <rtdbg.h>
  21. #include "cpu_ops_common.h"
  22. #ifdef RT_USING_SMP
  23. #ifdef RT_USING_FDT
  24. #include <dtb_node.h>
  25. static rt_uint64_t cpu_release_addr[RT_CPUS_NR];
  26. static int spin_table_cpu_init(rt_uint32_t cpuid)
  27. {
  28. struct dtb_node *cpu = get_cpu_node(cpuid);
  29. if (!cpu)
  30. return -1; /* uninitialized cpu node in fdt */
  31. int size;
  32. rt_uint64_t *phead = (rt_uint64_t*)dtb_node_get_dtb_node_property_value(cpu, "cpu-release-addr", &size);
  33. cpu_release_addr[cpuid] = fdt64_to_cpu(*phead);
  34. LOG_D("Using release address 0x%p for CPU %d", cpu_release_addr[cpuid], cpuid);
  35. return 0;
  36. }
  37. static int spin_table_cpu_boot(rt_uint32_t cpuid)
  38. {
  39. rt_uint64_t secondary_entry_pa = get_secondary_entry_pa();
  40. if (!secondary_entry_pa)
  41. return -1;
  42. // map release_addr to addressable place
  43. void *rel_va = (void *)cpu_release_addr[cpuid];
  44. #ifdef RT_USING_SMART
  45. rel_va = rt_ioremap(rel_va, sizeof(cpu_release_addr[0]));
  46. #endif
  47. if (!rel_va)
  48. {
  49. LOG_E("IO remap failing");
  50. return -1;
  51. }
  52. __asm__ volatile("str %0, [%1]" ::"rZ"(secondary_entry_pa), "r"(rel_va));
  53. __asm__ volatile("dsb sy");
  54. __asm__ volatile("sev");
  55. rt_iounmap(rel_va);
  56. return 0;
  57. }
  58. #endif /* RT_USING_FDT */
  59. struct cpu_ops_t cpu_ops_spin_tbl = {
  60. .method = "spin-table",
  61. #ifdef RT_USING_FDT
  62. .cpu_init = spin_table_cpu_init,
  63. .cpu_boot = spin_table_cpu_boot,
  64. #endif
  65. };
  66. #endif /* RT_USING_SMP */