1 /*
2  * Copyright (c) 2006-2024, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2024-04-19     Shell        Fixup UP irq spinlock
9  * 2024-05-22     Shell        Add UP cpu object and
10  *                             maintain the rt_current_thread inside it
11  */
12 #include <rthw.h>
13 #include <rtthread.h>
14 
15 static struct rt_cpu _cpu;
16 
17 /**
18  * @brief   Initialize a static spinlock object.
19  *
20  * @param   lock is a pointer to the spinlock to initialize.
21  */
rt_spin_lock_init(struct rt_spinlock * lock)22 void rt_spin_lock_init(struct rt_spinlock *lock)
23 {
24     RT_UNUSED(lock);
25 }
26 
27 /**
28  * @brief   This function will lock the spinlock, will lock the thread scheduler.
29  *
30  * @note    If the spinlock is locked, the current CPU will keep polling the spinlock state
31  *          until the spinlock is unlocked.
32  *
33  * @param   lock is a pointer to the spinlock.
34  */
rt_spin_lock(struct rt_spinlock * lock)35 void rt_spin_lock(struct rt_spinlock *lock)
36 {
37     rt_enter_critical();
38     RT_SPIN_LOCK_DEBUG(lock);
39 }
40 
41 /**
42  * @brief   This function will unlock the spinlock, will unlock the thread scheduler.
43  *
44  * @note    If the scheduling function is called before unlocking, it will be scheduled in this function.
45  *
46  * @param   lock is a pointer to the spinlock.
47  */
rt_spin_unlock(struct rt_spinlock * lock)48 void rt_spin_unlock(struct rt_spinlock *lock)
49 {
50     rt_base_t critical_level;
51     RT_SPIN_UNLOCK_DEBUG(lock, critical_level);
52     rt_exit_critical_safe(critical_level);
53 }
54 
55 /**
56  * @brief   This function will disable the local interrupt and then lock the spinlock, will lock the thread scheduler.
57  *
58  * @note    If the spinlock is locked, the current CPU will keep polling the spinlock state
59  *          until the spinlock is unlocked.
60  *
61  * @param   lock is a pointer to the spinlock.
62  *
63  * @return  Return current cpu interrupt status.
64  */
rt_spin_lock_irqsave(struct rt_spinlock * lock)65 rt_base_t rt_spin_lock_irqsave(struct rt_spinlock *lock)
66 {
67     rt_base_t level;
68     RT_UNUSED(lock);
69     level = rt_hw_interrupt_disable();
70     rt_enter_critical();
71     RT_SPIN_LOCK_DEBUG(lock);
72     return level;
73 }
74 
75 /**
76  * @brief   This function will unlock the spinlock and then restore current cpu interrupt status, will unlock the thread scheduler.
77  *
78  * @note    If the scheduling function is called before unlocking, it will be scheduled in this function.
79  *
80  * @param   lock is a pointer to the spinlock.
81  *
82  * @param   level is interrupt status returned by rt_spin_lock_irqsave().
83  */
rt_spin_unlock_irqrestore(struct rt_spinlock * lock,rt_base_t level)84 void rt_spin_unlock_irqrestore(struct rt_spinlock *lock, rt_base_t level)
85 {
86     rt_base_t critical_level;
87     RT_SPIN_UNLOCK_DEBUG(lock, critical_level);
88     rt_exit_critical_safe(critical_level);
89     rt_hw_interrupt_enable(level);
90 }
91 
92 /**
93  * @brief   This fucntion will return current cpu object.
94  *
95  * @return  Return a pointer to the current cpu object.
96  */
rt_cpu_self(void)97 struct rt_cpu *rt_cpu_self(void)
98 {
99     return &_cpu;
100 }
101 
102 /**
103  * @brief   This fucntion will return the cpu object corresponding to index.
104  *
105  * @param   index is the index of target cpu object.
106  *
107  * @return  Return a pointer to the cpu object corresponding to index.
108  */
rt_cpu_index(int index)109 struct rt_cpu *rt_cpu_index(int index)
110 {
111     return index == 0 ? &_cpu : RT_NULL;
112 }
113