aboutsummaryrefslogtreecommitdiff
path: root/pk
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2015-11-16 14:02:07 -0800
committerAndrew Waterman <waterman@cs.berkeley.edu>2015-11-16 14:02:07 -0800
commit197a8b81e4bbf61c497c93c0ac4630a33ab11b1c (patch)
tree27b984cf55295258d9ab31294402c66f328b53a4 /pk
parent47f9e06fc2c696dfb1054d730cde888f1ac75d07 (diff)
downloadpk-197a8b81e4bbf61c497c93c0ac4630a33ab11b1c.zip
pk-197a8b81e4bbf61c497c93c0ac4630a33ab11b1c.tar.gz
pk-197a8b81e4bbf61c497c93c0ac4630a33ab11b1c.tar.bz2
Use IPIs to wake up harts
This has the side effect of testing the IPI mechanism. Still not sure this is the best approach to booting, but it works...
Diffstat (limited to 'pk')
-rw-r--r--pk/mentry.S23
-rw-r--r--pk/minit.c43
-rw-r--r--pk/mtrap.h1
-rw-r--r--pk/pk.h1
4 files changed, 31 insertions, 37 deletions
diff --git a/pk/mentry.S b/pk/mentry.S
index f26e2dd..26ed83c 100644
--- a/pk/mentry.S
+++ b/pk/mentry.S
@@ -175,23 +175,20 @@ mentry:
csrr a0, mhartid
bnez a0, .LmultiHart
- # boot hart 0
csrw mscratch, sp
- j machine_init
+ j init_first_hart
.LmultiHart:
- # mhartid may not be contiguous, so generate a hart id using AMOs
- la a0, num_harts_booted
- la a1, 1
- amoadd.w a0, a1, (a0)
-
- # allocate stack
- sll t0, a0, RISCV_PGSHIFT
- add sp, sp, t0
- csrw mscratch, sp
- # boot this hart
- j machine_init
+ # wait for IPI to signal that it's time to boot
+ wfi
+ csrr a0, mip
+ andi a0, a0, MIP_MSIP
+ beqz a0, .LmultiHart
+
+ fence
+ csrr sp, mscratch
+ j init_other_hart
.Linterrupt:
sll a0, a0, 1 # discard MSB
diff --git a/pk/minit.c b/pk/minit.c
index 6ff6be9..712ea67 100644
--- a/pk/minit.c
+++ b/pk/minit.c
@@ -4,7 +4,6 @@
uintptr_t mem_size;
uint32_t num_harts;
-uint32_t num_harts_booted = 1;
static void mstatus_init()
{
@@ -55,16 +54,29 @@ static void fp_init()
#endif
}
-void hls_init(uint32_t hart_id, uintptr_t* csrs)
+void hls_init(uint32_t id, uintptr_t* csrs)
{
- hls_t* hls = OTHER_HLS(hart_id);
+ hls_t* hls = OTHER_HLS(id);
memset(hls, 0, sizeof(*hls));
- hls->hart_id = hart_id;
+ hls->hart_id = id;
hls->csrs = csrs;
+
+ // tell the hart where its stack is, then wake it up
+ csrs[CSR_MSCRATCH] = (uintptr_t)(OTHER_STACK_TOP(id) - MENTRY_FRAME_SIZE);
+ mb();
+ csrs[CSR_MIPI] = 0;
+}
+
+static void init_hart()
+{
+ mstatus_init();
+ fp_init();
}
-static void init_first_hart()
+void init_first_hart()
{
+ init_hart();
+
memset(HLS(), 0, sizeof(*HLS()));
file_init();
parse_device_tree();
@@ -77,8 +89,10 @@ static void init_first_hart()
boot_loader(args);
}
-static void init_other_hart(uint32_t hart_id)
+void init_other_hart()
{
+ init_hart();
+
// wait until virtual memory is enabled
do {
mb();
@@ -86,22 +100,5 @@ static void init_other_hart(uint32_t hart_id)
write_csr(sptbr, root_page_table);
- // then make sure we're in bounds
- if (hart_id >= num_harts) {
- while (1)
- wfi();
- }
-
boot_other_hart();
}
-
-void machine_init(uint32_t hart_id)
-{
- mstatus_init();
- fp_init();
-
- if (hart_id == 0)
- init_first_hart();
- else
- init_other_hart(hart_id);
-}
diff --git a/pk/mtrap.h b/pk/mtrap.h
index 375d549..61624d3 100644
--- a/pk/mtrap.h
+++ b/pk/mtrap.h
@@ -238,6 +238,7 @@ void hls_init(uint32_t hart_id, uintptr_t* csrs);
// hart-local storage, at top of stack
#define HLS() ((hls_t*)(MACHINE_STACK_TOP() - HLS_SIZE))
+#define OTHER_STACK_TOP(id) (MACHINE_STACK_TOP() + RISCV_PGSIZE * ((id) - HLS()->hart_id))
#define OTHER_HLS(id) ((hls_t*)((void*)HLS() + RISCV_PGSIZE * ((id) - HLS()->hart_id)))
#endif // !__ASSEMBLER__
diff --git a/pk/pk.h b/pk/pk.h
index 6aec2ad..08821b4 100644
--- a/pk/pk.h
+++ b/pk/pk.h
@@ -48,7 +48,6 @@ extern "C" {
extern uintptr_t mem_size;
extern int have_vm;
extern uint32_t num_harts;
-extern uint32_t num_harts_booted;
struct mainvars* parse_args(struct mainvars*);
void printk(const char* s, ...);