cpuport_smp.c 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2018/12/23 Bernard The first version
  9. * 2018/12/27 Jesven Add secondary cpu boot
  10. */
  11. #include <rthw.h>
  12. #include <rtthread.h>
  13. #include <stdint.h>
  14. #include "board.h"
  15. #include <encoding.h>
  16. #include <clint.h>
  17. #include <atomic.h>
  18. #ifdef RT_USING_SMP
  19. int rt_hw_cpu_id(void)
  20. {
  21. return read_csr(mhartid);
  22. }
  23. void rt_hw_spin_lock_init(rt_hw_spinlock_t *lock)
  24. {
  25. ((spinlock_t *)lock)->lock = 0;
  26. }
  27. void rt_hw_spin_lock(rt_hw_spinlock_t *lock)
  28. {
  29. spinlock_lock((spinlock_t *)lock);
  30. }
  31. void rt_hw_spin_unlock(rt_hw_spinlock_t *lock)
  32. {
  33. spinlock_unlock((spinlock_t *)lock);
  34. }
  35. void rt_hw_ipi_send(int ipi_vector, unsigned int cpu_mask)
  36. {
  37. int idx;
  38. for (idx = 0; idx < RT_CPUS_NR; idx ++)
  39. {
  40. if (cpu_mask & (1 << idx))
  41. {
  42. clint_ipi_send(idx);
  43. }
  44. }
  45. }
  46. extern rt_base_t secondary_boot_flag;
  47. void rt_hw_secondary_cpu_up(void)
  48. {
  49. mb();
  50. secondary_boot_flag = 0xa55a;
  51. }
  52. extern void rt_hw_scondary_interrupt_init(void);
  53. extern int rt_hw_tick_init(void);
  54. extern int rt_hw_clint_ipi_enable(void);
  55. void secondary_cpu_c_start(void)
  56. {
  57. rt_hw_spin_lock(&_cpus_lock);
  58. /* initialize interrupt controller */
  59. rt_hw_scondary_interrupt_init();
  60. rt_hw_tick_init();
  61. rt_hw_clint_ipi_enable();
  62. rt_system_scheduler_start();
  63. }
  64. void rt_hw_secondary_cpu_idle_exec(void)
  65. {
  66. asm volatile ("wfi");
  67. }
  68. #endif /*RT_USING_SMP*/