Skip to content
Permalink
Browse files

Apply CPU features checks so that management CPU cores that can't run…

… supervisor kernels aren't allowed to join the container thread scheduler. Also trim redundant asm from RISC-V boot code
  • Loading branch information...
diodesign committed Jul 11, 2019
1 parent c694d79 commit 2a00bc042e8d2e8fc923e75039618c186e633e5b
Showing with 35 additions and 10 deletions.
  1. +11 −2 src/kernel/scheduler.rs
  2. +0 −5 src/platform/riscv/asm/entry.s
  3. +24 −3 src/platform/riscv/src/cpu.rs
@@ -34,10 +34,19 @@ pub fn init(device_tree_buf: &u8) -> Result<(), Cause>
}

/* activate preemptive multitasking. each CPU core should call this
to start running software threads */
to start running software threads. CPU cores that can't run user and supervisor-level
code aren't allowed to join the scheduler: these cores are likely auxiliary or
management CPUs that have to park waiting for interrupts */
pub fn start()
{
platform::timer::start();
if platform::cpu::features_priv_check(platform::cpu::PrivilegeMode::User) == true
{
platform::timer::start();
}
else
{
klog!("Not joining the scheduler, awaiting IRQs");
}
}

/* a thread has been running for one timeslice, triggering a timer interrupt.
@@ -79,8 +79,3 @@ enter_kernel:
infinite_loop:
wfi
j infinite_loop

is_boot_cpu:
# set a0 to true to indicate this is the boot CPU
li a0, 1
j enter_kernel
@@ -22,6 +22,10 @@ const EXTENSIONS: &'static [&'static str] = &["a", "b", "c", "d", "e", "f", "g",
"k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
"u", "v", "w", "x", "y", "z"];

/* flags within CPUFeatures, derived from misa */
const CPUFEATURES_SUPERVISOR_MODE: usize = 1 << 18; /* supervisor mode is implemented */
const CPUFEATURES_USER_MODE: usize = 1 << 20; /* user mode is implemented */

/* levels of privilege accepted by the kernel */
#[derive(Copy, Clone, Debug)]
pub enum PrivilegeMode
@@ -126,6 +130,23 @@ pub fn features() -> CPUFeatures
return read_csr!(misa) as CPUFeatures;
}

/* check that this CPU core has sufficient features to run code at the given privilege level
=> required = privilege level required
<= return true if CPU can run code at the required privilege, false if not */
pub fn features_priv_check(required: PrivilegeMode) -> bool
{
let cpu = read_csr!(misa);

/* all RISC-V cores provide machine (kernel) mode. Diosix requires supervisor mode for user mode */
match (required, cpu & CPUFEATURES_SUPERVISOR_MODE != 0, cpu & CPUFEATURES_USER_MODE != 0)
{
( PrivilegeMode::Kernel, _, _) => true,
(PrivilegeMode::Supervisor, true, _) => true,
( PrivilegeMode::User, true, true) => true,
_ => false
}
}

/* provide an iterator that lists descriptive strings about this CPU core */
pub fn describe() -> CPUDescriptionIter
{
@@ -180,9 +201,9 @@ impl Iterator for CPUDescriptionIter
check anyway for diagnostic purposes */
Some(match self.misa >> width_shift
{
1 => "32-bit RISC-V, extensions: ",
2 => "64-bit RISC-V, extensions: ",
_ => "Unsupported RISC-V, extensions: "
1 => "32-bit RISC-V, ext: ",
2 => "64-bit RISC-V, ext: ",
_ => "Unsupported RISC-V, ext: "
})
},
CPUDescriptionState::Extension(index) =>

0 comments on commit 2a00bc0

Please sign in to comment.
You can’t perform that action at this time.