1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <arch/barrier.h>
4 #include <arch/encoding.h>
5 #include <arch/smp/smp.h>
6 #include <arch/smp/atomic.h>
7 #include <console/console.h>
10 void smp_pause(int working_hartid
)
12 #define SYNCA (OTHER_HLS(working_hartid)->entry.sync_a)
13 #define SYNCB (OTHER_HLS(working_hartid)->entry.sync_b)
15 int hartid
= read_csr(mhartid
);
17 if (hartid
!= working_hartid
) {
18 /* waiting for work hart */
21 } while (atomic_read(&SYNCA
) != 0x01234567);
23 clear_csr(mstatus
, MSTATUS_MIE
);
24 write_csr(mie
, MIP_MSIP
);
26 /* count how many cores enter the halt */
27 atomic_add(&SYNCB
, 1);
31 __asm__
volatile ("wfi");
32 } while ((read_csr(mip
) & MIP_MSIP
) == 0);
34 HLS()->entry
.fn(HLS()->entry
.arg
);
36 /* Initialize the counter and
37 * mark the work hart into smp_pause */
38 atomic_set(&SYNCB
, 0);
39 atomic_set(&SYNCA
, 0x01234567);
41 /* waiting for other Hart to enter the halt */
44 } while (atomic_read(&SYNCB
) + 1 < CONFIG_MAX_CPUS
);
46 /* initialize for the next call */
47 atomic_set(&SYNCA
, 0);
48 atomic_set(&SYNCB
, 0);
54 void smp_resume(void (*fn
)(void *), void *arg
)
56 int hartid
= read_csr(mhartid
);
59 die("must pass a non-null function pointer\n");
61 for (int i
= 0; i
< CONFIG_MAX_CPUS
; i
++) {
62 OTHER_HLS(i
)->entry
.fn
= fn
;
63 OTHER_HLS(i
)->entry
.arg
= arg
;
66 for (int i
= 0; i
< CONFIG_MAX_CPUS
; i
++)
70 if (HLS()->entry
.fn
== NULL
)
71 die("entry fn not set\n");
73 HLS()->entry
.fn(HLS()->entry
.arg
);