aboutsummaryrefslogtreecommitdiff
path: root/pk/minit.c
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2015-05-29 18:24:28 -0700
committerAndrew Waterman <waterman@cs.berkeley.edu>2015-05-29 18:24:28 -0700
commitcffdcee338ea682c74fa778244241e2f060199bf (patch)
tree17cbc43440db766cc5aba5a03afdc07e83e03e93 /pk/minit.c
parent835d03d2160be9ee50ba5fd892554ef62fcb13b8 (diff)
downloadpk-cffdcee338ea682c74fa778244241e2f060199bf.zip
pk-cffdcee338ea682c74fa778244241e2f060199bf.tar.gz
pk-cffdcee338ea682c74fa778244241e2f060199bf.tar.bz2
Make boot loader/SBI changes to support SMP Linux
Diffstat (limited to 'pk/minit.c')
-rw-r--r--pk/minit.c48
1 files changed, 35 insertions, 13 deletions
diff --git a/pk/minit.c b/pk/minit.c
index 47c19b0..a040e2b 100644
--- a/pk/minit.c
+++ b/pk/minit.c
@@ -3,6 +3,7 @@
uintptr_t mem_size;
uint32_t num_harts;
+uint32_t num_harts_booted = 1;
static void mstatus_init()
{
@@ -22,21 +23,18 @@ static void mstatus_init()
if (EXTRACT_FIELD(ms, MSTATUS_VM) != VM_CHOICE)
have_vm = 0;
+
+ clear_csr(mip, MIP_MSIP);
+ set_csr(mie, MIP_MSIP);
}
static void memory_init()
{
if (mem_size == 0)
panic("could not determine memory capacity");
-}
-static void hart_init()
-{
if (num_harts == 0)
panic("could not determine number of harts");
-
- if (num_harts != 1)
- panic("TODO: SMP support");
}
static void fp_init()
@@ -54,23 +52,47 @@ static void fp_init()
#endif
}
-static void mailbox_init()
+static void hls_init(uint32_t hart_id)
{
- memset(MAILBOX(), 0, MAILBOX_SIZE);
+ memset(HLS(), 0, sizeof(*HLS()));
+ HLS()->hart_id = hart_id;
}
-void machine_init()
+static void init_first_hart()
{
- mailbox_init();
file_init();
struct mainvars arg_buffer;
struct mainvars *args = parse_args(&arg_buffer);
- mstatus_init();
memory_init();
- hart_init();
- fp_init();
vm_init();
boot_loader(args);
}
+
+static void init_other_hart()
+{
+ // wait until virtual memory is enabled
+ while (root_page_table == NULL)
+ asm volatile ("" ::: "memory");
+ mb();
+ write_csr(sptbr, root_page_table);
+
+ // then make sure we're in bounds
+ if (HLS()->hart_id >= num_harts)
+ panic("too many harts");
+
+ boot_other_hart();
+}
+
+void machine_init(uint32_t hart_id)
+{
+ hls_init(hart_id);
+ mstatus_init();
+ fp_init();
+
+ if (hart_id == 0)
+ init_first_hart();
+ else
+ init_other_hart();
+}