aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2016-07-28 14:22:12 -0700
committerAndrew Waterman <waterman@cs.berkeley.edu>2016-07-28 14:22:51 -0700
commitd42f458b6a7145533912cca3e268e2f6951e3992 (patch)
tree7a251b26ad9b8d86d075c8dfc32638d5cf9e8573
parentcd6dec56d6f6ead58ec009df0f0394136bbc4fa5 (diff)
downloadpk-d42f458b6a7145533912cca3e268e2f6951e3992.zip
pk-d42f458b6a7145533912cca3e268e2f6951e3992.tar.gz
pk-d42f458b6a7145533912cca3e268e2f6951e3992.tar.bz2
Don't let other harts boot before HLS is initialized
Use IPIs to signal them.
-rw-r--r--machine/configstring.c5
-rw-r--r--machine/mentry.S9
-rw-r--r--machine/minit.c6
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();
}