1818#include <sbi.h>
1919#include <encoding.h>
2020
21+ #ifdef ARCH_MM_MMU
22+ #include "mmu.h"
23+ #endif
24+
2125#ifdef RT_USING_SMP
2226#include "tick.h"
2327#include "interrupt.h"
@@ -54,6 +58,10 @@ volatile rt_ubase_t rt_interrupt_to_thread = 0;
5458 */
5559volatile rt_ubase_t rt_thread_switch_interrupt_flag = 0 ;
5660
61+ #ifdef ARCH_MM_MMU
62+ static rt_ubase_t * percpu_hartid ;
63+ #endif
64+
5765void * _rt_hw_stack_init (rt_ubase_t * sp , rt_ubase_t ra , rt_ubase_t sstatus )
5866{
5967 rt_hw_switch_frame_t frame = (rt_hw_switch_frame_t )((rt_ubase_t )sp - sizeof (struct rt_hw_switch_frame ));
@@ -71,10 +79,19 @@ int rt_hw_cpu_id(void)
7179#ifndef RT_USING_SMP
7280 return 0 ;
7381#else
74- /* Currently, the hartid is stored in the satp register. */
75- rt_ubase_t hart_id ;
76- asm volatile ("csrr %0, satp" : "=r" (hart_id ));
77- return hart_id ;
82+ if (rt_kmem_pvoff () != 0 )
83+ {
84+ return * percpu_hartid ;
85+ }
86+ else
87+ {
88+ // if not enable MMU or pvoff==0, read hartid from satp register
89+ rt_ubase_t hartid ;
90+ asm volatile ("csrr %0, satp" : "=r" (hartid ));
91+ return hartid ;
92+ }
93+
94+
7895#endif /* RT_USING_SMP */
7996}
8097
@@ -170,11 +187,19 @@ void rt_hw_secondary_cpu_up(void)
170187 rt_uint64_t entry_pa ;
171188 int hart , ret ;
172189
173- /* translate kernel virtual _start to physical address.
174- * TODO: Virtual-to-physical translation is not needed here
175- * because &_start is already a physical address on this platform.
176- */
190+ /* translate kernel virtual _start to physical address. */
191+ #ifdef ARCH_MM_MMU
192+ if (rt_kmem_pvoff () != 0 )
193+ {
194+ entry_pa = (rt_uint64_t )rt_kmem_v2p (& _start );
195+ }
196+ else
197+ {
198+ entry_pa = (rt_uint64_t )& _start ;
199+ }
200+ #else
177201 entry_pa = (rt_uint64_t )& _start ;
202+ #endif /* ARCH_MM_MMU */
178203
179204 for (hart = 0 ; hart < RT_CPUS_NR ; hart ++ )
180205 {
@@ -191,8 +216,31 @@ void rt_hw_secondary_cpu_up(void)
191216 }
192217}
193218
219+ #ifdef ARCH_MM_MMU
220+ void rt_hw_percpu_hartid_init (rt_ubase_t * percpu_ptr , rt_ubase_t hartid )
221+ {
222+ rt_ubase_t * percpu_hartid_paddr ;
223+ rt_size_t percpu_size = (rt_size_t )((rt_ubase_t )& __percpu_end - (rt_ubase_t )& __percpu_start );
224+
225+ percpu_hartid = percpu_ptr ;
226+
227+ // from virtual address to physical address
228+ percpu_ptr = (rt_ubase_t * )((rt_ubase_t )percpu_ptr + (rt_ubase_t )rt_kmem_pvoff ());
229+ percpu_hartid_paddr = percpu_ptr ;
230+
231+
232+ /* Save to the real area */
233+ * (rt_ubase_t * )((void * )percpu_hartid_paddr + hartid * percpu_size ) = hartid ;
234+ }
235+ #endif /* ARCH_MM_MMU */
236+
194237void secondary_cpu_entry (void )
195238{
239+
240+ #ifdef RT_USING_SMART
241+ /* switch to kernel address space */
242+ rt_hw_aspace_switch (& rt_kernel_space );
243+ #endif
196244 /* The PLIC peripheral interrupts are currently handled by the boot_hart. */
197245 /* Enable the Supervisor-Timer bit in SIE */
198246 rt_hw_tick_init ();
0 commit comments