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