Skip to content

Commit

Permalink
Add hypervisor extension (#2841)
Browse files Browse the repository at this point in the history
This PR implements v0.6.2 of the RISC-V Hypervisor Extension.

The implementation was inspired by José Martins' and colleagues' work
described in [1]. Much of the microarchitecture and essentially all of
the code is new, but their implementation served as our baseline.
We thank them for trailblazing hypervisor support in rocket-chip.

Note that this PR only includes the mechanisms to virtualize the hart
itself. Virtualized interrupt controllers, IOMMUs, etc. are future work.
Lots of future work.

Note also that some features are (legally) not implemented. Currently,
misa.H is not writable, something we may or may not choose to fix.
The mtinst and htinst CSRs are hardwired to 0, placing
additional onus on hypervisor software to use the HLVX instruction.

[1] "A First Look at RISC-V Virtualization from an Embedded Systems Perspective", https://arxiv.org/abs/2103.14951

Co-authored-by: John Ingalls <john.ingalls@sifive.com>
  • Loading branch information
aswaterman and ingallsj committed Dec 27, 2021
1 parent 4df857a commit 185cac8
Show file tree
Hide file tree
Showing 20 changed files with 1,045 additions and 236 deletions.
17 changes: 15 additions & 2 deletions src/main/resources/vsrc/RoccBlackBox.v
Expand Up @@ -10,6 +10,7 @@ module RoccBlackBox
coreDataBits,
coreDataBytes,
paddrBits,
vaddrBitsExtended,
FPConstants_RM_SZ,
fLen,
FPConstants_FLAGS_SZ )
Expand All @@ -32,9 +33,15 @@ module RoccBlackBox
input rocc_cmd_bits_status_wfi,
input [31:0] rocc_cmd_bits_status_isa,
input [PRV_SZ-1:0] rocc_cmd_bits_status_dprv,
input rocc_cmd_bits_status_dv,
input [PRV_SZ-1:0] rocc_cmd_bits_status_prv,
input rocc_cmd_bits_status_v,
input rocc_cmd_bits_status_sd,
input [26:0] rocc_cmd_bits_status_zero2,
input [22:0] rocc_cmd_bits_status_zero2,
input rocc_cmd_bits_status_mpv,
input rocc_cmd_bits_status_gva,
input rocc_cmd_bits_status_mbe,
input rocc_cmd_bits_status_sbe,
input [1:0] rocc_cmd_bits_status_sxl,
input [1:0] rocc_cmd_bits_status_uxl,
input rocc_cmd_bits_status_sd_rv32,
Expand All @@ -51,7 +58,7 @@ module RoccBlackBox
input [1:0] rocc_cmd_bits_status_mpp,
input [0:0] rocc_cmd_bits_status_spp,
input rocc_cmd_bits_status_mpie,
input rocc_cmd_bits_status_hpie,
input rocc_cmd_bits_status_ube,
input rocc_cmd_bits_status_spie,
input rocc_cmd_bits_status_upie,
input rocc_cmd_bits_status_mie,
Expand All @@ -73,6 +80,7 @@ module RoccBlackBox
output rocc_mem_req_bits_no_alloc,
output rocc_mem_req_bits_no_xcpt,
output [1:0] rocc_mem_req_bits_dprv,
output rocc_mem_req_bits_dv,
output [coreDataBits-1:0] rocc_mem_req_bits_data,
output [coreDataBytes-1:0] rocc_mem_req_bits_mask,
output rocc_mem_s1_kill,
Expand All @@ -83,6 +91,8 @@ module RoccBlackBox
output rocc_mem_s2_kill,
input rocc_mem_s2_uncached,
input [paddrBits-1:0] rocc_mem_s2_paddr,
input [vaddrBitsExtended-1:0] rocc_mem_s2_gpa,
input rocc_mem_s2_gpa_is_pte,
input rocc_mem_resp_valid,
input [coreMaxAddrBits-1:0] rocc_mem_resp_bits_addr,
input [dcacheReqTagBits-1:0] rocc_mem_resp_bits_tag,
Expand All @@ -97,11 +107,14 @@ module RoccBlackBox
input [coreDataBits-1:0] rocc_mem_resp_bits_data_raw,
input [coreDataBits-1:0] rocc_mem_resp_bits_store_data,
input [1:0] rocc_mem_resp_bits_dprv,
input rocc_mem_resp_bits_dv,
input rocc_mem_replay_next,
input rocc_mem_s2_xcpt_ma_ld,
input rocc_mem_s2_xcpt_ma_st,
input rocc_mem_s2_xcpt_pf_ld,
input rocc_mem_s2_xcpt_pf_st,
input rocc_mem_s2_xcpt_gf_ld,
input rocc_mem_s2_xcpt_gf_st,
input rocc_mem_s2_xcpt_ae_ld,
input rocc_mem_s2_xcpt_ae_st,
input rocc_mem_ordered,
Expand Down
Expand Up @@ -81,7 +81,7 @@ class RocketLogicalTreeNode(
def getOMInterruptTargets(): Seq[OMInterruptTarget] = {
Seq(OMInterruptTarget(
hartId = tile.rocketParams.hartId,
modes = OMModes.getModes(tile.rocketParams.core.hasSupervisorMode)
modes = OMModes.getModes(tile.rocketParams.core.hasSupervisorMode, tile.rocketParams.core.useHypervisor)
))
}

Expand Down
Expand Up @@ -5,11 +5,13 @@ package freechips.rocketchip.diplomaticobjectmodel.model

sealed trait PrivilegedArchitectureExtension extends OMEnum
case object MachineLevelISA extends PrivilegedArchitectureExtension
case object HypervisorLevelISA extends PrivilegedArchitectureExtension
case object SupervisorLevelISA extends PrivilegedArchitectureExtension

object PrivilegedArchitectureExtensions {
val specifications = Map[PrivilegedArchitectureExtension, String](
MachineLevelISA -> "Machine-Level ISA",
HypervisorLevelISA -> "Hypervisor-Level ISA",
SupervisorLevelISA -> "Supervisor-Level ISA"
)

Expand All @@ -36,7 +38,8 @@ object ISAExtensions {
C -> "C Standard Extension for Compressed Instruction",
B -> "B Standard Extension for Bit Manipulation",
U -> "The RISC‑V Instruction Set Manual, Volume II: Privileged Architecture",
S -> "Supervisor-Level ISA"
S -> "Supervisor-Level ISA",
H -> "H Standard Extension for Hypervisor",
)

def specVersion(extension: OMExtensionType, version: String): OMSpecification = OMSpecification(specifications(extension), version)
Expand Down
3 changes: 3 additions & 0 deletions src/main/scala/diplomaticobjectmodel/model/OMISA.scala
Expand Up @@ -15,6 +15,7 @@ case object C extends OMExtensionType
case object B extends OMExtensionType
case object U extends OMExtensionType
case object S extends OMExtensionType
case object H extends OMExtensionType

trait OMAddressTranslationMode extends OMEnum
case object Bare extends OMAddressTranslationMode
Expand Down Expand Up @@ -44,6 +45,7 @@ case class OMISA(
v: Option[OMVectorExtension] = None,
u: Option[OMSpecification],
s: Option[OMSpecification],
h: Option[OMSpecification],
addressTranslationModes: Seq[OMAddressTranslationMode],
customExtensions: Seq[OMCustomExtensionSpecification],
_types: Seq[String] = Seq("OMISA", "OMCompoundType")
Expand Down Expand Up @@ -105,6 +107,7 @@ object OMISA {
c = coreParams.useCompressed.option(isaExtSpec(C, "2.0")),
u = (coreParams.hasSupervisorMode || coreParams.useUser).option(isaExtSpec(U, "1.10")),
s = coreParams.hasSupervisorMode.option(isaExtSpec(S, "1.10")),
h = coreParams.useHypervisor.option(isaExtSpec(H, "0.6")),
addressTranslationModes = Seq(addressTranslationModes),
customExtensions = customExtensions
)
Expand Down
10 changes: 5 additions & 5 deletions src/main/scala/diplomaticobjectmodel/model/OMPLIC.scala
Expand Up @@ -4,15 +4,15 @@ package freechips.rocketchip.diplomaticobjectmodel.model

sealed trait OMPrivilegeMode extends OMEnum
case object OMMachineMode extends OMPrivilegeMode
case object OMHypervisorMode extends OMPrivilegeMode
case object OMSupervisorMode extends OMPrivilegeMode
case object OMUserMode extends OMPrivilegeMode

object OMModes {
def getModes(hasSupervisorMode: Boolean): Seq[OMPrivilegeMode] = {
hasSupervisorMode match {
case false => Seq(OMMachineMode)
case true => Seq(OMMachineMode, OMSupervisorMode)
}
def getModes(hasSupervisorMode: Boolean, hasHypervisorMode: Boolean): Seq[OMPrivilegeMode] = {
Seq(OMMachineMode) ++
(if (hasHypervisorMode) Seq(OMHypervisorMode) else Seq()) ++
(if (hasSupervisorMode) Seq(OMSupervisorMode) else Seq())
}
}

Expand Down

0 comments on commit 185cac8

Please sign in to comment.