summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAtish Patra <[email protected]>2018-12-17 16:35:07 -0800
committerAtish Patra <[email protected]>2018-12-20 15:55:27 -0800
commit84971c0bc03245dc8092ec5a1119450a62ee2d47 (patch)
tree5c073afe66b0d1cb48aabcae5bb5b6746de37734
parente0a660ec5bdb11820600388d084f461f0bef8ed7 (diff)
Use wfi for coldboot finish call.
Signed-off-by: Atish Patra <[email protected]>
-rw-r--r--blob/fw_common.S5
-rw-r--r--include/sbi/sbi_hart.h2
-rw-r--r--lib/sbi_hart.c33
-rw-r--r--lib/sbi_init.c2
4 files changed, 24 insertions, 18 deletions
diff --git a/blob/fw_common.S b/blob/fw_common.S
index db0f7f7d..a2685cf2 100644
--- a/blob/fw_common.S
+++ b/blob/fw_common.S
@@ -122,7 +122,10 @@ _start_warm:
csrw mie, zero
csrw mip, zero
- /* HART ID should be within expected limit */
+ /* set MSIE bit to receive IPI */
+ li a2, MIP_MSIP
+ csrw mie, a2
+ /* HART ID should be withing expected limit */
csrr a6, mhartid
li a5, PLAT_HART_COUNT
bge a6, a5, _start_hang
diff --git a/include/sbi/sbi_hart.h b/include/sbi/sbi_hart.h
index 38032ed8..c77ffd23 100644
--- a/include/sbi/sbi_hart.h
+++ b/include/sbi/sbi_hart.h
@@ -36,6 +36,6 @@ struct sbi_scratch *sbi_hart_id_to_scratch(struct sbi_scratch *scratch,
void sbi_hart_wait_for_coldboot(struct sbi_scratch *scratch, u32 hartid);
-void sbi_hart_wake_coldboot_harts(struct sbi_scratch *scratch);
+void sbi_hart_wake_coldboot_harts(struct sbi_scratch *scratch, u32 hartid);
#endif
diff --git a/lib/sbi_hart.c b/lib/sbi_hart.c
index db833c78..30f4f03f 100644
--- a/lib/sbi_hart.c
+++ b/lib/sbi_hart.c
@@ -264,31 +264,34 @@ struct sbi_scratch *sbi_hart_id_to_scratch(struct sbi_scratch *scratch,
}
#define NO_HOTPLUG_BITMAP_SIZE __riscv_xlen
-static spinlock_t coldboot_holding_pen_lock = SPIN_LOCK_INITIALIZER;
-static volatile unsigned long coldboot_holding_pen = 0;
void sbi_hart_wait_for_coldboot(struct sbi_scratch *scratch, u32 hartid)
{
- unsigned long done;
+ unsigned long mipval;
struct sbi_platform *plat = sbi_platform_ptr(scratch);
+ sbi_printf("%s: In hartid = [%d]\n", __func__, hartid);
if ((sbi_platform_hart_count(plat) <= hartid) ||
(NO_HOTPLUG_BITMAP_SIZE <= hartid))
sbi_hart_hang();
+ do {
+ wfi();
+ mipval = csr_read(mip);
+ /* Make sure the hart woke because of ipi */
+ } while (!(mipval && MIP_MSIP) );
- while (1) {
- spin_lock(&coldboot_holding_pen_lock);
- done = coldboot_holding_pen;
- spin_unlock(&coldboot_holding_pen_lock);
- if (done)
- break;
- cpu_relax();
- }
+ csr_clear(mip, MIP_MSIP);
}
-void sbi_hart_wake_coldboot_harts(struct sbi_scratch *scratch)
+void sbi_hart_wake_coldboot_harts(struct sbi_scratch *scratch, u32 hartid)
{
- spin_lock(&coldboot_holding_pen_lock);
- coldboot_holding_pen = 1;
- spin_unlock(&coldboot_holding_pen_lock);
+ struct sbi_platform *plat = sbi_platform_ptr(scratch);
+ int max_hart = sbi_platform_hart_count(plat);
+
+ for(int i = 0; i < max_hart ; i++) {
+ /* send an IPI to every other hart */
+ if (i != hartid)
+ sbi_platform_ipi_inject(plat, i, hartid);
+ }
+
}
diff --git a/lib/sbi_init.c b/lib/sbi_init.c
index 52c63fa3..82384b39 100644
--- a/lib/sbi_init.c
+++ b/lib/sbi_init.c
@@ -96,7 +96,7 @@ static void __attribute__((noreturn)) init_coldboot(struct sbi_scratch *scratch,
sbi_hart_mark_available(hartid);
if (!sbi_platform_has_hart_hotplug(plat))
- sbi_hart_wake_coldboot_harts(scratch);
+ sbi_hart_wake_coldboot_harts(scratch, hartid);
sbi_hart_boot_next(hartid, scratch->next_arg1,
scratch->next_addr, scratch->next_mode);