[v1 2/4] RISC-V: Hypervisor ext: support Privileged Spec 1.12

Vineet Gupta vineetg@rivosinc.com
Tue Dec 21 02:34:13 GMT 2021


This is the Hypervisor Extension 1.0

 - Hypervisor Memory-Management Instructions
   HFENCE.VVMA, HFENCE.GVMA,

 - Hypervisor Virtual Machine Load and Store Instructions
   HLV.B, HLV.BU,          HSV.B,
   HLV.H, HLV.HU, HLVX.HU, HSB.H,
   HLV.W, HLV.WU, HLVX.WU, HSV.W,
   HLV.D,                  HSV.D

 - Hypervisor CSRs (some new, some address changed)
   hstatus, hedeleg, hideleg, hie, hcounteren, hgeie, htval, hip, hvip,
   htinst, hgeip, henvcfg, henvcfgh, hgatp, hcontext, htimedelta, htimedeltah,
   vsstatus, vsie, vstvec, vsscratch, vsepc, vscause, vstval, vsip, vsatp,

Note that following were added already as part of svinval extension
support:
   HINVAL.GVMA, HINVAL.VVMA

Signed-off-by: Vineet Gupta <vineetg@rivosinc.com>
---
 bfd/cpu-riscv.c            |  1 +
 bfd/cpu-riscv.h            |  1 +
 bfd/elfxx-riscv.c          |  6 +++
 include/opcode/riscv-opc.h | 90 ++++++++++++++++++++++++++++++++++++++
 include/opcode/riscv.h     |  2 +
 opcodes/riscv-opc.c        | 26 ++++++++++-
 6 files changed, 124 insertions(+), 2 deletions(-)

diff --git a/bfd/cpu-riscv.c b/bfd/cpu-riscv.c
index 813f2c3df8d9..5038029ce014 100644
--- a/bfd/cpu-riscv.c
+++ b/bfd/cpu-riscv.c
@@ -117,6 +117,7 @@ const struct riscv_spec riscv_priv_specs[] =
   {"1.9.1", PRIV_SPEC_CLASS_1P9P1},
   {"1.10",  PRIV_SPEC_CLASS_1P10},
   {"1.11",  PRIV_SPEC_CLASS_1P11},
+  {"1.12",  PRIV_SPEC_CLASS_1P12},
 };
 
 /* Get the corresponding CSR version class by giving privilege
diff --git a/bfd/cpu-riscv.h b/bfd/cpu-riscv.h
index ed5ee7e60d58..b251d6312b82 100644
--- a/bfd/cpu-riscv.h
+++ b/bfd/cpu-riscv.h
@@ -32,6 +32,7 @@ enum riscv_spec_class
   PRIV_SPEC_CLASS_1P9P1,
   PRIV_SPEC_CLASS_1P10,
   PRIV_SPEC_CLASS_1P11,
+  PRIV_SPEC_CLASS_1P12,
   PRIV_SPEC_CLASS_DRAFT,
 };
 
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index c575ab093f96..074e637dd590 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -2406,6 +2406,12 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
 	      || riscv_subset_supports (rps, "zve32f"));
     case INSN_CLASS_SVINVAL:
       return riscv_subset_supports (rps, "svinval");
+    case INSN_CLASS_SVINVAL_AND_H:
+      return riscv_subset_supports (rps, "svinval");
+    /* TODO: currently Hypervisor extension is enabled by default.
+             switch to its own arch string when implemented.  */
+    case INSN_CLASS_H:
+      return riscv_subset_supports (rps, "i");
     default:
       rps->error_handler
         (_("internal: unreachable INSN_CLASS_*"));
diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
index 2486f13c9fd3..da9ef81d33f5 100644
--- a/include/opcode/riscv-opc.h
+++ b/include/opcode/riscv-opc.h
@@ -1987,6 +1987,22 @@
 #define MASK_VDOTUVV  0xfc00707f
 #define MATCH_VFDOTVV  0xe4001057
 #define MASK_VFDOTVV  0xfc00707f
+#define MASK_HLV      0xfff0707f
+#define MATCH_HLVB    0x60004073
+#define MATCH_HLVBU   0x60104073
+#define MATCH_HLVH    0x64004073
+#define MATCH_HLVHU   0x64104073
+#define MATCH_HLVXHU  0x64304073
+#define MATCH_HLVW    0x68004073
+#define MATCH_HLVXWU  0x68304073
+#define MATCH_HLVWU   0x68104073
+#define MATCH_HLVD    0x6c004073
+
+#define MASK_HSV      0xfe007fff
+#define MATCH_HSVB    0x62004073
+#define MATCH_HSVH    0x66004073
+#define MATCH_HSVW    0x6a004073
+#define MATCH_HSVD    0x6e004073
 /* Svinval instruction.  */
 #define MATCH_SINVAL_VMA 0x16000073
 #define MASK_SINVAL_VMA 0xfe007fff
@@ -1994,6 +2010,10 @@
 #define MASK_SFENCE_W_INVAL 0xffffffff
 #define MATCH_SFENCE_INVAL_IR 0x18100073
 #define MASK_SFENCE_INVAL_IR 0xffffffff
+#define MASK_HFENCE_VVMA  0xfe007fff
+#define MATCH_HFENCE_VVMA 0x22000073
+#define MASK_HFENCE_GVMA  0xfe007fff
+#define MATCH_HFENCE_GVMA 0x62000073
 #define MATCH_HINVAL_VVMA 0x26000073
 #define MASK_HINVAL_VVMA 0xfe007fff
 #define MATCH_HINVAL_GVMA 0x66000073
@@ -2211,6 +2231,33 @@
 #define CSR_MHPMEVENT29 0x33d
 #define CSR_MHPMEVENT30 0x33e
 #define CSR_MHPMEVENT31 0x33f
+/* Hypervisor Extension v1.0 (Privileged spec 1.12). */
+#define CSR_HSTATUS     0x600
+#define CSR_HEDELEG     0x602
+#define CSR_HIDELEG     0x603
+#define CSR_HIE         0x604
+#define CSR_HCOUNTEREN  0x606
+#define CSR_HGEIE       0x607
+#define CSR_HTVAL       0x643
+#define CSR_HIP         0x644
+#define CSR_HVIP        0x645
+#define CSR_HTINST      0x64a
+#define CSR_HGEIP       0xe12
+#define CSR_HENVCFG     0x60a
+#define CSR_HENVCFGH    0x61a
+#define CSR_HGATP       0x680
+#define CSR_HCONTEXT    0x6a8
+#define CSR_HTIMEDELTA  0x605
+#define CSR_HTIMEDELTAH 0x615
+#define CSR_VSSTATUS    0x200
+#define CSR_VSIE        0x204
+#define CSR_VSTVEC      0x205
+#define CSR_VSSCRATCH   0x240
+#define CSR_VSEPC       0x241
+#define CSR_VSCAUSE     0x242
+#define CSR_VSTVAL      0x243
+#define CSR_VSIP        0x244
+#define CSR_VSATP       0x280
 #define CSR_MBASE 0x380
 #define CSR_MBOUND 0x381
 #define CSR_MIBASE 0x382
@@ -2553,8 +2600,23 @@ DECLARE_INSN(c_sdsp, MATCH_C_SDSP, MASK_C_SDSP)
 DECLARE_INSN(sinval_vma, MATCH_SINVAL_VMA, MASK_SINVAL_VMA)
 DECLARE_INSN(sfence_w_inval, MATCH_SFENCE_W_INVAL, MASK_SFENCE_W_INVAL)
 DECLARE_INSN(sfence_inval_ir, MATCH_SFENCE_INVAL_IR, MASK_SFENCE_INVAL_IR)
+DECLARE_INSN(hfence_vvma, MATCH_HFENCE_VVMA, MASK_HFENCE)
+DECLARE_INSN(hfence_gvma, MATCH_HFENCE_GVMA, MASK_HFENCE)
 DECLARE_INSN(hinval_vvma, MATCH_HINVAL_VVMA, MASK_HINVAL_VVMA)
 DECLARE_INSN(hinval_gvma, MATCH_HINVAL_GVMA, MASK_HINVAL_GVMA)
+DECLARE_INSN(hlv_b,   MATCH_HLVB,   MASK_HLV)
+DECLARE_INSN(hlv_h,   MATCH_HLVH,   MASK_HLV)
+DECLARE_INSN(hlv_w,   MATCH_HLVW,   MASK_HLV)
+DECLARE_INSN(hlv_d,   MATCH_HLVD,   MASK_HLV)
+DECLARE_INSN(hlv_bu,  MATCH_HLVBU,  MASK_HLV)
+DECLARE_INSN(hlv_hu,  MATCH_HLVHU,  MASK_HLV)
+DECLARE_INSN(hlv_wu,  MATCH_HLVWU,  MASK_HLV)
+DECLARE_INSN(hlvx_hu, MATCH_HLVXHU, MASK_HLV)
+DECLARE_INSN(hlvx_wu, MATCH_HLVXWU, MASK_HLV)
+DECLARE_INSN(hsv_b,   MATCH_HSVB,   MASK_HSV)
+DECLARE_INSN(hsv_h,   MATCH_HSVH,   MASK_HSV)
+DECLARE_INSN(hsv_w,   MATCH_HSVW,   MASK_HSV)
+DECLARE_INSN(hsv_d,   MATCH_HSVD,   MASK_HSV)
 #endif /* DECLARE_INSN */
 #ifdef DECLARE_CSR
 /* Privileged CSRs.  */
@@ -2770,6 +2832,34 @@ DECLARE_CSR(mhpmevent28, CSR_MHPMEVENT28, CSR_CLASS_I, PRIV_SPEC_CLASS_1P9P1, PR
 DECLARE_CSR(mhpmevent29, CSR_MHPMEVENT29, CSR_CLASS_I, PRIV_SPEC_CLASS_1P9P1, PRIV_SPEC_CLASS_DRAFT)
 DECLARE_CSR(mhpmevent30, CSR_MHPMEVENT30, CSR_CLASS_I, PRIV_SPEC_CLASS_1P9P1, PRIV_SPEC_CLASS_DRAFT)
 DECLARE_CSR(mhpmevent31, CSR_MHPMEVENT31, CSR_CLASS_I, PRIV_SPEC_CLASS_1P9P1, PRIV_SPEC_CLASS_DRAFT)
+/* Hypervisor Ext v1.0 (Privileged spec 1.12).  */
+/* TODO: Fix to CSR_CLASS_H when explicit h-ext arch string is introduced.  */
+DECLARE_CSR(hstatus,     CSR_HSTATUS,     CSR_CLASS_I, PRIV_SPEC_CLASS_1P12, PRIV_SPEC_CLASS_DRAFT)
+DECLARE_CSR(hedeleg,     CSR_HEDELEG,     CSR_CLASS_I, PRIV_SPEC_CLASS_1P12, PRIV_SPEC_CLASS_DRAFT)
+DECLARE_CSR(hideleg,     CSR_HIDELEG,     CSR_CLASS_I, PRIV_SPEC_CLASS_1P12, PRIV_SPEC_CLASS_DRAFT)
+DECLARE_CSR(hie,         CSR_HIE,         CSR_CLASS_I, PRIV_SPEC_CLASS_1P12, PRIV_SPEC_CLASS_DRAFT)
+DECLARE_CSR(hcounteren,  CSR_HCOUNTEREN,  CSR_CLASS_I, PRIV_SPEC_CLASS_1P12, PRIV_SPEC_CLASS_DRAFT)
+DECLARE_CSR(hgeie,       CSR_HGEIE,       CSR_CLASS_I, PRIV_SPEC_CLASS_1P12, PRIV_SPEC_CLASS_DRAFT)
+DECLARE_CSR(htval,       CSR_HTVAL,       CSR_CLASS_I, PRIV_SPEC_CLASS_1P12, PRIV_SPEC_CLASS_DRAFT)
+DECLARE_CSR(hip,         CSR_HIP,         CSR_CLASS_I, PRIV_SPEC_CLASS_1P12, PRIV_SPEC_CLASS_DRAFT)
+DECLARE_CSR(hvip,        CSR_HVIP,        CSR_CLASS_I, PRIV_SPEC_CLASS_1P12, PRIV_SPEC_CLASS_DRAFT)
+DECLARE_CSR(htinst,      CSR_HTINST,      CSR_CLASS_I, PRIV_SPEC_CLASS_1P12, PRIV_SPEC_CLASS_DRAFT)
+DECLARE_CSR(hgeip,       CSR_HGEIP,       CSR_CLASS_I, PRIV_SPEC_CLASS_1P12, PRIV_SPEC_CLASS_DRAFT)
+DECLARE_CSR(henvcfg,     CSR_HENVCFG,     CSR_CLASS_I, PRIV_SPEC_CLASS_1P12, PRIV_SPEC_CLASS_DRAFT)
+DECLARE_CSR(henvcfgh,    CSR_HENVCFGH,    CSR_CLASS_I, PRIV_SPEC_CLASS_1P12, PRIV_SPEC_CLASS_DRAFT)
+DECLARE_CSR(hgatp,       CSR_HGATP,       CSR_CLASS_I, PRIV_SPEC_CLASS_1P12, PRIV_SPEC_CLASS_DRAFT)
+DECLARE_CSR(hcontext,    CSR_HCONTEXT,    CSR_CLASS_I, PRIV_SPEC_CLASS_1P12, PRIV_SPEC_CLASS_DRAFT)
+DECLARE_CSR(htimedelta,  CSR_HTIMEDELTA,  CSR_CLASS_I, PRIV_SPEC_CLASS_1P12, PRIV_SPEC_CLASS_DRAFT)
+DECLARE_CSR(htimedeltah, CSR_HTIMEDELTAH, CSR_CLASS_I, PRIV_SPEC_CLASS_1P12, PRIV_SPEC_CLASS_DRAFT)
+DECLARE_CSR(vsstatus,    CSR_VSSTATUS,    CSR_CLASS_I, PRIV_SPEC_CLASS_1P12, PRIV_SPEC_CLASS_DRAFT)
+DECLARE_CSR(vsie,        CSR_VSIE,        CSR_CLASS_I, PRIV_SPEC_CLASS_1P12, PRIV_SPEC_CLASS_DRAFT)
+DECLARE_CSR(vstvec,      CSR_VSTVEC,      CSR_CLASS_I, PRIV_SPEC_CLASS_1P12, PRIV_SPEC_CLASS_DRAFT)
+DECLARE_CSR(vsscratch,   CSR_VSSCRATCH,   CSR_CLASS_I, PRIV_SPEC_CLASS_1P12, PRIV_SPEC_CLASS_DRAFT)
+DECLARE_CSR(vsepc,       CSR_VSEPC,       CSR_CLASS_I, PRIV_SPEC_CLASS_1P12, PRIV_SPEC_CLASS_DRAFT)
+DECLARE_CSR(vscause,     CSR_VSCAUSE,     CSR_CLASS_I, PRIV_SPEC_CLASS_1P12, PRIV_SPEC_CLASS_DRAFT)
+DECLARE_CSR(vstval,      CSR_VSTVAL,      CSR_CLASS_I, PRIV_SPEC_CLASS_1P12, PRIV_SPEC_CLASS_DRAFT)
+DECLARE_CSR(vsip,        CSR_VSIP,        CSR_CLASS_I, PRIV_SPEC_CLASS_1P12, PRIV_SPEC_CLASS_DRAFT)
+DECLARE_CSR(vsatp,       CSR_VSATP,       CSR_CLASS_I, PRIV_SPEC_CLASS_1P12, PRIV_SPEC_CLASS_DRAFT)
 /* Dropped CSRs.  */
 DECLARE_CSR(mbase, CSR_MBASE, CSR_CLASS_I, PRIV_SPEC_CLASS_1P9P1, PRIV_SPEC_CLASS_1P10)
 DECLARE_CSR(mbound, CSR_MBOUND, CSR_CLASS_I, PRIV_SPEC_CLASS_1P9P1, PRIV_SPEC_CLASS_1P10)
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index cbc90b00008f..e054d0b18666 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -388,6 +388,8 @@ enum riscv_insn_class
   INSN_CLASS_V,
   INSN_CLASS_ZVEF,
   INSN_CLASS_SVINVAL,
+  INSN_CLASS_H,
+  INSN_CLASS_SVINVAL_AND_H,
 };
 
 /* This structure holds information for a particular instruction.  */
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index f220006fc93f..f5f4b9a28dcd 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -1729,8 +1729,30 @@ const struct riscv_opcode riscv_opcodes[] =
 {"sinval.vma",      0, INSN_CLASS_SVINVAL, "s,t", MATCH_SINVAL_VMA, MASK_SINVAL_VMA, match_opcode, 0 },
 {"sfence.w.inval",  0, INSN_CLASS_SVINVAL, "",    MATCH_SFENCE_W_INVAL, MASK_SFENCE_W_INVAL, match_opcode, 0 },
 {"sfence.inval.ir", 0, INSN_CLASS_SVINVAL, "",    MATCH_SFENCE_INVAL_IR, MASK_SFENCE_INVAL_IR, match_opcode, 0 },
-{"hinval.vvma",     0, INSN_CLASS_SVINVAL, "s,t", MATCH_HINVAL_VVMA, MASK_HINVAL_VVMA, match_opcode, 0 },
-{"hinval.gvma",     0, INSN_CLASS_SVINVAL, "s,t", MATCH_HINVAL_GVMA, MASK_HINVAL_GVMA, match_opcode, 0 },
+
+/* Svinval instructions + Hypervisor Ext v1.0.  */
+{"hinval.vvma",     0, INSN_CLASS_SVINVAL_AND_H, "s,t", MATCH_HINVAL_VVMA, MASK_HINVAL_VVMA, match_opcode, 0 },
+{"hinval.gvma",     0, INSN_CLASS_SVINVAL_AND_H, "s,t", MATCH_HINVAL_GVMA, MASK_HINVAL_GVMA, match_opcode, 0 },
+{"hfence.vvma",     0, INSN_CLASS_SVINVAL_AND_H, "s,t", MATCH_HFENCE_VVMA, MASK_HFENCE_VVMA, match_opcode, 0 },
+{"hfence.gvma",     0, INSN_CLASS_SVINVAL_AND_H, "",    MATCH_HFENCE_GVMA, MASK_HFENCE_GVMA|MASK_RS1|MASK_RS2, match_opcode, 0 },
+{"hfence.gvma",     0, INSN_CLASS_SVINVAL_AND_H, "s",   MATCH_HFENCE_GVMA, MASK_HFENCE_GVMA|MASK_RS2, match_opcode, 0 },
+{"hfence.gvma",     0, INSN_CLASS_SVINVAL_AND_H, "s,t", MATCH_HFENCE_GVMA, MASK_HFENCE_GVMA, match_opcode, 0 },
+
+/* Hypervisor Ext v1.0 (Privileged spec 1.12).  */
+{"hlv.b",       0, INSN_CLASS_H, "d,0(s)", MATCH_HLVB,   MASK_HLV, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"hlv.bu",      0, INSN_CLASS_H, "d,0(s)", MATCH_HLVBU,  MASK_HLV, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"hlv.h",       0, INSN_CLASS_H, "d,0(s)", MATCH_HLVH,   MASK_HLV, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"hlv.hu",      0, INSN_CLASS_H, "d,0(s)", MATCH_HLVHU,  MASK_HLV, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"hlvx.hu",     0, INSN_CLASS_H, "d,0(s)", MATCH_HLVXHU, MASK_HLV, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"hlv.w",       0, INSN_CLASS_H, "d,0(s)", MATCH_HLVW,   MASK_HLV, match_opcode, INSN_DREF|INSN_4_BYTE },
+{"hlv.wu",     64, INSN_CLASS_H, "d,0(s)", MATCH_HLVWU,  MASK_HLV, match_opcode, INSN_DREF|INSN_4_BYTE },
+{"hlvx.wu",     0, INSN_CLASS_H, "d,0(s)", MATCH_HLVXWU, MASK_HLV, match_opcode, INSN_DREF|INSN_4_BYTE },
+{"hlv.d",      64, INSN_CLASS_H, "d,0(s)", MATCH_HLVD,   MASK_HLV, match_opcode, INSN_DREF|INSN_8_BYTE },
+
+{"hsv.b",       0, INSN_CLASS_H, "t,0(s)", MATCH_HSVB,   MASK_HSV, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"hsv.h",       0, INSN_CLASS_H, "t,0(s)", MATCH_HSVH,   MASK_HSV, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"hsv.w",       0, INSN_CLASS_H, "t,0(s)", MATCH_HSVW,   MASK_HSV, match_opcode, INSN_DREF|INSN_4_BYTE },
+{"hsv.d",      64, INSN_CLASS_H, "t,0(s)", MATCH_HSVD,   MASK_HSV, match_opcode, INSN_DREF|INSN_8_BYTE },
 
 /* Terminate the list.  */
 {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
-- 
2.30.2



More information about the Binutils mailing list