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