diff options
author | Andrew Waterman <waterman@cs.berkeley.edu> | 2016-07-28 14:22:12 -0700 |
---|---|---|
committer | Andrew Waterman <waterman@cs.berkeley.edu> | 2016-07-28 14:22:51 -0700 |
commit | d42f458b6a7145533912cca3e268e2f6951e3992 (patch) | |
tree | 7a251b26ad9b8d86d075c8dfc32638d5cf9e8573 | |
parent | cd6dec56d6f6ead58ec009df0f0394136bbc4fa5 (diff) | |
download | riscv-pk-d42f458b6a7145533912cca3e268e2f6951e3992.zip riscv-pk-d42f458b6a7145533912cca3e268e2f6951e3992.tar.gz riscv-pk-d42f458b6a7145533912cca3e268e2f6951e3992.tar.bz2 |
Don't let other harts boot before HLS is initialized
Use IPIs to signal them.
-rw-r--r-- | machine/configstring.c | 5 | ||||
-rw-r--r-- | machine/mentry.S | 9 | ||||
-rw-r--r-- | machine/minit.c | 6 |
3 files changed, 12 insertions, 8 deletions
diff --git a/machine/configstring.c b/machine/configstring.c index c935eb8..fb2fed7 100644 --- a/machine/configstring.c +++ b/machine/configstring.c @@ -75,9 +75,12 @@ static void query_harts(const char* config_string) snprintf(buf, sizeof buf, "core{%d{%d{timecmp", core, hart); res = query_config_string(config_string, buf); assert(res.start); + hls->timecmp = (void*)(uintptr_t)get_uint(res); mb(); - hls->timecmp = (void*)(uintptr_t)get_uint(res); + + // wake up the hart + *hls->ipi = 1; num_harts++; } diff --git a/machine/mentry.S b/machine/mentry.S index 6bdc7e6..9d2fe75 100644 --- a/machine/mentry.S +++ b/machine/mentry.S @@ -234,9 +234,16 @@ do_reset: .LmultiHart: #if MAX_HARTS > 1 + # wait for an IPI to signal that it's safe to boot + wfi + csrr a1, mip + andi a1, a1, MIP_MSIP + beqz a1, .LmultiHart + # make sure our hart id is within a valid range + fence li a1, MAX_HARTS bltu a0, a1, init_other_hart - wfi #endif + wfi j .LmultiHart diff --git a/machine/minit.c b/machine/minit.c index 4a1ddc6..5aae387 100644 --- a/machine/minit.c +++ b/machine/minit.c @@ -143,12 +143,6 @@ void init_first_hart() void init_other_hart() { hart_init(); - - // wait until hart 0 discovers us - while (*(uint64_t * volatile *)&HLS()->timecmp == NULL) - ; - mb(); - hart_plic_init(); boot_other_hart(); } |