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  * 2019-07-28     zdzn         add smp support
10  */
11 
12 #include <rthw.h>
13 #include <rtthread.h>
14 #include <board.h>
15 #include "cp15.h"
16 
rt_hw_cpu_id(void)17 int rt_hw_cpu_id(void)
18 {
19     int cpu_id;
20     __asm__ volatile (
21             "mrc p15, 0, %0, c0, c0, 5"
22             :"=r"(cpu_id)
23             );
24     cpu_id &= 0xf;
25     return cpu_id;
26 };
27 
28 
29 #ifdef RT_USING_SMP
rt_hw_spin_lock_init(rt_hw_spinlock_t * lock)30 void rt_hw_spin_lock_init(rt_hw_spinlock_t *lock)
31 {
32     lock->slock = 0;
33 }
34 
rt_hw_spin_lock(rt_hw_spinlock_t * lock)35 void rt_hw_spin_lock(rt_hw_spinlock_t *lock)
36 {
37     unsigned long tmp;
38     unsigned long newval;
39     rt_hw_spinlock_t lockval;
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     {
57         __WFE();
58         lockval.tickets.owner = *(volatile unsigned short *)(&lock->tickets.owner);
59     }
60 
61     __DMB();
62 }
63 
rt_hw_spin_unlock(rt_hw_spinlock_t * lock)64 void rt_hw_spin_unlock(rt_hw_spinlock_t *lock)
65 {
66     __DMB();
67     lock->tickets.owner++;
68     __DSB();
69     __SEV();
70 }
71 #endif /*RT_USING_SMP*/
72 
73 /**
74  * @addtogroup ARM CPU
75  */
76 /*@{*/
77 
78 
79 /*@}*/
80