cpu_spin_table.c 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  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 <ioremap.h>
  12. #include "cpu.h"
  13. #ifdef RT_USING_FDT
  14. #include <dtb_node.h>
  15. #include "entry_point.h"
  16. #define get_cpu_node(cpuid) _cpu_node[cpuid]
  17. extern struct dtb_node *_cpu_node[];
  18. static rt_uint64_t cpu_release_addr[RT_CPUS_NR];
  19. static int spin_table_cpu_init(rt_uint32_t cpuid)
  20. {
  21. struct dtb_node *cpu = get_cpu_node(cpuid);
  22. if (!cpu)
  23. return -1;
  24. int size;
  25. rt_uint64_t head = (rt_uint64_t)dtb_node_get_dtb_node_property_value(cpu, "cpu-release-addr", &size);
  26. cpu_release_addr[cpuid] = fdt64_to_cpu(head);
  27. return 0;
  28. }
  29. static int spin_table_cpu_boot(rt_uint32_t cpuid)
  30. {
  31. rt_uint64_t secondary_entry_pa = (rt_uint64_t)_secondary_cpu_entry + PV_OFFSET;
  32. // map release_addr to addressable place
  33. void *rel_va = rt_ioremap((void *)cpu_release_addr[cpuid], sizeof(cpu_release_addr[0]));
  34. if (!rel_va)
  35. return -1;
  36. __asm__ volatile ("str %0, [%1]"::"rZ"(secondary_entry_pa), "r"(rel_va));
  37. __asm__ volatile ("dsb sy");
  38. __asm__ volatile ("sev");
  39. rt_iounmap(rel_va);
  40. return 0;
  41. }
  42. #endif /* RT_USING_FDT */
  43. struct cpu_ops_t cpu_ops_spin_tbl = {
  44. .method = "spin-table",
  45. #ifdef RT_USING_FDT
  46. .cpu_init = spin_table_cpu_init,
  47. .cpu_boot = spin_table_cpu_boot,
  48. #endif
  49. };