1 /**************************************************************************//**
2 *
3 * @copyright (C) 2019 Nuvoton Technology Corp. All rights reserved.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Change Logs:
8 * Date            Author       Notes
9 * 2022-8-16       Wayne        First version
10 *
11 ******************************************************************************/
12 
13 #include <rtthread.h>
14 
15 #if defined(RT_USING_SMP)
16 #include "drv_common.h"
17 
18 
19 #define DEF_COUNTER_ADDR_RTP  (3*1024*1024)
20 #define DEF_COUNTER_ADDR_A35  ((0x80000000+DEF_COUNTER_ADDR_RTP)|UNCACHEABLE)
21 
22 #if defined(USE_MA35D1_SUBM)
23     #define DEF_COUNTER_ADDR   DEF_COUNTER_ADDR_RTP
24 #else
25     #define DEF_COUNTER_ADDR   DEF_COUNTER_ADDR_A35
26 #endif
27 
happy_counter(void * pdata)28 void happy_counter(void *pdata)
29 {
30     uint32_t counter = 0;
31     while (1)
32     {
33         rt_kprintf("cpu-%d %d\r\n", rt_hw_cpu_id(), counter++);
34         rt_thread_mdelay(1000);
35     }
36 }
37 
go_happy_counter(void)38 void go_happy_counter(void)
39 {
40     rt_thread_t tid = rt_thread_create("cpu-1", happy_counter, RT_NULL,  2048, 10, 20);
41     RT_ASSERT(tid != RT_NULL);
42 
43     rt_thread_control(tid, RT_THREAD_CTRL_BIND_CPU, (void *)1);
44 
45     rt_thread_startup(tid);
46 }
47 MSH_CMD_EXPORT(go_happy_counter, go happy counter);
48 
happy_memcpy(void * pdata)49 void happy_memcpy(void *pdata)
50 {
51     volatile uint32_t counter = 0;
52     void *srcbuf, *dstbuf;
53     rt_tick_t last, now;
54 
55 #define DEF_BUF_SIZE 4096
56 #define DEF_TIMES    500000
57     srcbuf = rt_malloc_align(DEF_BUF_SIZE, nu_cpu_dcache_line_size());
58     dstbuf = rt_malloc_align(DEF_BUF_SIZE, nu_cpu_dcache_line_size());
59 
60     now = rt_tick_get();
61     while (counter < DEF_TIMES)
62     {
63         rt_memcpy(dstbuf, srcbuf, DEF_BUF_SIZE);
64         counter++;
65     }
66     last = rt_tick_get();
67 
68     if (rt_hw_cpu_id() == 1)
69         rt_thread_mdelay(1000);
70 
71     rt_kprintf("%d Bytes copied by cpu-%d in %d ms\n", DEF_TIMES * DEF_BUF_SIZE, rt_hw_cpu_id(), last - now);
72 
73     rt_free_align(srcbuf);
74     rt_free_align(dstbuf);
75 }
76 
go_happy_memcpy_0_1(void)77 void go_happy_memcpy_0_1(void)
78 {
79     rt_thread_t tid0, tid1;
80 
81     tid0 = rt_thread_create("cpu-0", happy_memcpy, RT_NULL,  2048, 10, 20);
82     RT_ASSERT(tid0 != RT_NULL);
83     rt_thread_control(tid0, RT_THREAD_CTRL_BIND_CPU, (void *)0);
84 
85     tid1 = rt_thread_create("cpu-1", happy_memcpy, RT_NULL,  2048, 10, 20);
86     RT_ASSERT(tid1 != RT_NULL);
87     rt_thread_control(tid1, RT_THREAD_CTRL_BIND_CPU, (void *)1);
88 
89     rt_thread_startup(tid0);
90     rt_thread_startup(tid1);
91 }
92 MSH_CMD_EXPORT(go_happy_memcpy_0_1, go happy memcpy on dual - core);
93 
go_happy_memcpy_0(void)94 void go_happy_memcpy_0(void)
95 {
96     rt_thread_t tid0;
97 
98     tid0 = rt_thread_create("cpu-0", happy_memcpy, RT_NULL,  2048, 10, 20);
99     RT_ASSERT(tid0 != RT_NULL);
100     rt_thread_control(tid0, RT_THREAD_CTRL_BIND_CPU, (void *)0);
101 
102     rt_thread_startup(tid0);
103 }
104 MSH_CMD_EXPORT(go_happy_memcpy_0, go happy memcpy on core0);
105 
go_happy_memcpy_1(void)106 void go_happy_memcpy_1(void)
107 {
108     rt_thread_t tid1;
109 
110     tid1 = rt_thread_create("cpu-1", happy_memcpy, RT_NULL,  2048, 10, 20);
111     RT_ASSERT(tid1 != RT_NULL);
112     rt_thread_control(tid1, RT_THREAD_CTRL_BIND_CPU, (void *)1);
113 
114     rt_thread_startup(tid1);
115 }
116 MSH_CMD_EXPORT(go_happy_memcpy_1, go happy memcpy on core1);
117 
happy_mutex(void * parameter)118 static void happy_mutex(void *parameter)
119 {
120     rt_err_t ret;
121     rt_mutex_t psMutex = (rt_mutex_t)parameter;
122     uint32_t *pu32Counter = (uint32_t *)DEF_COUNTER_ADDR;
123 
124     *pu32Counter = 0;
125     while (1)
126     {
127         ret = rt_mutex_take(psMutex, RT_WAITING_FOREVER);
128         if (ret != RT_EOK)
129             continue;
130 
131         if (*pu32Counter >= 1000)
132         {
133             rt_mutex_release(psMutex);
134             break;
135         }
136         else
137             *pu32Counter = *pu32Counter + 1;
138 
139 #ifdef RT_USING_SMP
140         rt_kprintf("[%08x@CPU-%d] ->Inc %d@%08x\n", rt_thread_self(), rt_hw_cpu_id(), *pu32Counter, DEF_COUNTER_ADDR);
141 #else
142         rt_kprintf("[%08x]-> Inc %d@%08x\n", rt_thread_self(), *pu32Counter, DEF_COUNTER_ADDR);
143 #endif /* RT_USING_SMP */
144 
145         rt_mutex_release(psMutex);
146     }
147 }
148 
go_happy_mutex(void)149 static int go_happy_mutex(void)
150 {
151     rt_thread_t thread;
152     rt_mutex_t  sem = rt_mutex_create("mutexsem", RT_IPC_FLAG_PRIO);
153 
154     if(sem == RT_NULL)
155     {
156         rt_kprintf("create mutex failed");
157         return (int)-RT_ERROR;
158     }
159 
160     thread = rt_thread_create("mutex0", happy_mutex, (void *)sem, 2048, 25, 20);
161     if (thread != RT_NULL)
162     {
163 #ifdef RT_USING_SMP
164         rt_thread_control(thread, RT_THREAD_CTRL_BIND_CPU, (void *)0);
165 #endif
166         rt_thread_startup(thread);
167     }
168 
169     thread = rt_thread_create("mutex1", happy_mutex, (void *)sem, 2048, 25, 20);
170     if (thread != RT_NULL)
171     {
172 #ifdef RT_USING_SMP
173         rt_thread_control(thread, RT_THREAD_CTRL_BIND_CPU, (void *)1);
174 #endif
175         rt_thread_startup(thread);
176     }
177 
178     return 0;
179 }
180 MSH_CMD_EXPORT(go_happy_mutex, demo mutex);
181 
182 
183 #endif
184