cpuport.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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. * 2011-09-15 Bernard first version
  9. * 2018-11-22 Jesven add rt_hw_cpu_id()
  10. */
  11. #include <rthw.h>
  12. #include <rtthread.h>
  13. #include <board.h>
  14. rt_weak int rt_hw_cpu_id(void)
  15. {
  16. int cpu_id;
  17. __asm__ volatile (
  18. "mrc p15, 0, %0, c0, c0, 5"
  19. :"=r"(cpu_id)
  20. );
  21. cpu_id &= 0xf;
  22. return cpu_id;
  23. }
  24. #ifdef RT_USING_SMP
  25. void rt_hw_spin_lock_init(rt_hw_spinlock_t *lock)
  26. {
  27. lock->slock = 0;
  28. }
  29. void rt_hw_spin_lock(rt_hw_spinlock_t *lock)
  30. {
  31. unsigned long tmp;
  32. unsigned long newval;
  33. rt_hw_spinlock_t lockval;
  34. __asm__ __volatile__(
  35. "pld [%0]"
  36. ::"r"(&lock->slock)
  37. );
  38. __asm__ __volatile__(
  39. "1: ldrex %0, [%3]\n"
  40. " add %1, %0, %4\n"
  41. " strex %2, %1, [%3]\n"
  42. " teq %2, #0\n"
  43. " bne 1b"
  44. : "=&r" (lockval), "=&r" (newval), "=&r" (tmp)
  45. : "r" (&lock->slock), "I" (1 << 16)
  46. : "cc");
  47. while (lockval.tickets.next != lockval.tickets.owner) {
  48. __asm__ __volatile__("wfe":::"memory");
  49. lockval.tickets.owner = *(volatile unsigned short *)(&lock->tickets.owner);
  50. }
  51. __asm__ volatile ("dmb":::"memory");
  52. }
  53. void rt_hw_spin_unlock(rt_hw_spinlock_t *lock)
  54. {
  55. __asm__ volatile ("dmb":::"memory");
  56. lock->tickets.owner++;
  57. __asm__ volatile ("dsb ishst\nsev":::"memory");
  58. }
  59. #endif /*RT_USING_SMP*/
  60. /**
  61. * @addtogroup ARM CPU
  62. */
  63. /*@{*/
  64. /** shutdown CPU */
  65. void rt_hw_cpu_shutdown(void)
  66. {
  67. rt_base_t level;
  68. rt_kprintf("shutdown...\n");
  69. level = rt_hw_interrupt_disable();
  70. while (level)
  71. {
  72. RT_ASSERT(0);
  73. }
  74. }
  75. #ifdef RT_USING_CPU_FFS
  76. /**
  77. * This function finds the first bit set (beginning with the least significant bit)
  78. * in value and return the index of that bit.
  79. *
  80. * Bits are numbered starting at 1 (the least significant bit). A return value of
  81. * zero from any of these functions means that the argument was zero.
  82. *
  83. * @return return the index of the first bit set. If value is 0, then this function
  84. * shall return 0.
  85. */
  86. int __rt_ffs(int value)
  87. {
  88. return __builtin_ffs(value);
  89. }
  90. #endif
  91. /*@}*/