Skip to content

Commit

Permalink
add zicfilp extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
ved-rivos committed Nov 26, 2023
1 parent 305d7a9 commit 4d1a435
Show file tree
Hide file tree
Showing 11 changed files with 529 additions and 17 deletions.
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ SAIL_DEFAULT_INST += riscv_insts_zbkx.sail

SAIL_DEFAULT_INST += riscv_insts_zicond.sail

SAIL_DEFAULT_INST += riscv_zicfilp_regs.sail # Zicfilp state
SAIL_DEFAULT_INST += riscv_insts_zicfilp.sail # Zicfilp instructions

SAIL_DEFAULT_INST += riscv_insts_vext_utils.sail
SAIL_DEFAULT_INST += riscv_insts_vext_vset.sail
SAIL_DEFAULT_INST += riscv_insts_vext_arith.sail
Expand Down Expand Up @@ -95,6 +98,8 @@ SAIL_ARCH_SRCS += riscv_types_kext.sail # Shared/common code for the cryptogr

SAIL_STEP_SRCS = riscv_step_common.sail riscv_step_ext.sail riscv_decode_ext.sail riscv_fetch.sail riscv_step.sail
RVFI_STEP_SRCS = riscv_step_common.sail riscv_step_rvfi.sail riscv_decode_ext.sail riscv_fetch_rvfi.sail riscv_step.sail
SAIL_STEP_SRCS += riscv_step_zicfilp.sail
RVFI_STEP_SRCS += riscv_step_zicfilp.sail

# Control inclusion of 64-bit only riscv_analysis
ifeq ($(ARCH),RV32)
Expand Down
2 changes: 2 additions & 0 deletions model/riscv_csr_map.sail
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ mapping clause csr_name_map = 0xB00 <-> "mcycle"
mapping clause csr_name_map = 0xB02 <-> "minstret"
mapping clause csr_name_map = 0xB80 <-> "mcycleh"
mapping clause csr_name_map = 0xB82 <-> "minstreth"
/* machine security configuration */
mapping clause csr_name_map = 0x747 <-> "mseccfg"
/* TODO: other hpm counters and events */
/* trigger/debug */
mapping clause csr_name_map = 0x7a0 <-> "tselect"
Expand Down
5 changes: 4 additions & 1 deletion model/riscv_ext_regs.sail
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,12 @@ This function is called after above when running rvfi and allows the model
to be initialised differently (e.g. CHERI cap regs are initialised
to omnipotent instead of null).
*/
val init_zicfilp_regs : unit -> unit
val ext_rvfi_init : unit -> unit
function ext_rvfi_init () = {
x1 = x1 // to avoid hook being optimized out
x1 = x1; // to avoid hook being optimized out
/* Zicfilp register state */
init_zicfilp_regs();
}


Expand Down
179 changes: 179 additions & 0 deletions model/riscv_insts_zicfilp.sail
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
/*=======================================================================================*/
/* RISCV Sail Model */
/* */
/* This Sail RISC-V architecture model, comprising all files and */
/* directories except for the snapshots of the Lem and Sail libraries */
/* in the prover_snapshots directory (which include copies of their */
/* licences), is subject to the BSD two-clause licence below. */
/* */
/* Copyright (c) 2017-2023 */
/* Prashanth Mundkur */
/* Rishiyur S. Nikhil and Bluespec, Inc. */
/* Jon French */
/* Brian Campbell */
/* Robert Norton-Wright */
/* Alasdair Armstrong */
/* Thomas Bauereiss */
/* Shaked Flur */
/* Christopher Pulte */
/* Peter Sewell */
/* Alexander Richardson */
/* Hesham Almatary */
/* Jessica Clarke */
/* Microsoft, for contributions by Robert Norton-Wright and Nathaniel Wesley Filardo */
/* Peter Rugg */
/* Aril Computer Corp., for contributions by Scott Johnson */
/* Philipp Tomsich */
/* VRULL GmbH, for contributions by its employees */
/* Ved Shanbhogue */
/* */
/* All rights reserved. */
/* */
/* This software was developed by the above within the Rigorous */
/* Engineering of Mainstream Systems (REMS) project, partly funded by */
/* EPSRC grant EP/K008528/1, at the Universities of Cambridge and */
/* Edinburgh. */
/* */
/* This software was developed by SRI International and the University of */
/* Cambridge Computer Laboratory (Department of Computer Science and */
/* Technology) under DARPA/AFRL contract FA8650-18-C-7809 ("CIFV"), and */
/* under DARPA contract HR0011-18-C-0016 ("ECATS") as part of the DARPA */
/* SSITH research programme. */
/* */
/* This project has received funding from the European Research Council */
/* (ERC) under the European Union’s Horizon 2020 research and innovation */
/* programme (grant agreement 789108, ELVER). */
/* */
/* */
/* Redistribution and use in source and binary forms, with or without */
/* modification, are permitted provided that the following conditions */
/* are met: */
/* 1. Redistributions of source code must retain the above copyright */
/* notice, this list of conditions and the following disclaimer. */
/* 2. Redistributions in binary form must reproduce the above copyright */
/* notice, this list of conditions and the following disclaimer in */
/* the documentation and/or other materials provided with the */
/* distribution. */
/* */
/* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' */
/* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED */
/* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A */
/* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR */
/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF */
/* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND */
/* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, */
/* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT */
/* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF */
/* SUCH DAMAGE. */
/*=======================================================================================*/

/* ****************************************************************** */
/* This file specifies the instructions in the 'Zicfilp' extension. */
/* ****************************************************************** */
/* Forward-edge CFI: Landing pads */
/* Sail does not yet support H extension - this needs to be updated to
support henvcfg for VS when H extension support is included */
function zicfilp_xLPE() -> bool = {
/* When S-mode is implemented
* Priv xLPE
* M mseccfg.MLPE
* S/HS menvcfg.LPE
* VS henvcfg.LPE
* U/VU senvcfg.LPE
* When S-mode is not implemented
* Priv xLPE
* M mseccfg.MLPE
* U menvcfg.LPE
*/
if not(haveZicfilp())
then false
else if cur_privilege == Machine
then mseccfg.MLPE() == 0b1
else if cur_privilege == Supervisor
then menvcfg.LPE() == 0b1
else if not(haveSupMode())
then menvcfg.LPE() == 0b1
else senvcfg.LPE() == 0b1
}
/* extension to jalr */
function zicfilp_update_elp(rs1_reg : regidx, rd_reg : regidx) -> unit = {
/*
* An indirect branch using JALR, C.JALR, or C.JR with rs1 as x7 is termed
* a software guarded branch. Such branches do not need to land on a LPAD
* instruction and thus do not set ELP to LP_EXPECTED. JALR/C.JR/C.JALR
* using x1/x5 as source are returns; they do not set ELP to LP_EXPECTED.
*
* is_lp_expected = ( (JALR || C.JR || C.JALR) &&
* (rs1 != x1) && (rs1 != x5) && (rs1 != x7) ) ? 1 : 0;
*/
let is_lp_expected : bool = ((rs1_reg != 0b00001) & (rs1_reg != 0b00101) &
(rs1_reg != 0b00111));
if is_lp_expected == true & zicfilp_xLPE()
then elp = ElpState_to_bits(LP_EXPECTED);

}
/* AUIPC with rd=x0 is a lpad instruction when zicfilp is active else a no-op */
function zicfilp_lpad( lpl : bits(20) ) -> Retired = {
/* expected label is in x7 bits 31:12 */
let exp_lbl : bits(20) = x7[31..12];

if zicfilp_xLPE() & (elp == ElpState_to_bits(LP_EXPECTED)) then {
if ( (lpl != exp_lbl) & (lpl != 0b00000000000000000000) )
then { handle_sw_check_exception(LANDING_PAD_FAULT); RETIRE_FAIL }
else {elp = ElpState_to_bits(NO_LP_EXPECTED); RETIRE_SUCCESS };
} else {
RETIRE_SUCCESS
}
}
/* trap delivery extension */
function zicfilp_trap_extension(del_priv : Privilege) -> unit = {
/* When a trap is taken into privilege mode x, the xPELP is set
to ELP and ELP is set to NO_LP_EXPECTED. */
/* Sail does not have support for Debug mode - this needs to be
updated when Debug mode support is added */
if haveZicfilp() then {
match (del_priv, sizeof(xlen)) {
(Machine, 32 ) => {mstatush = update_MPELP(mstatush, elp)},
(Machine, _ ) => {mstatus = update_mstatus_MPELP(mstatus, elp)},
( _, _ ) => {mstatus = update_SPELP(mstatus, elp)},
};
elp = ElpState_to_bits(NO_LP_EXPECTED);
}
}
/* extension to MRET */
function zicfilp_set_elp_to_mpelp() -> unit = {
/* An MRET or SRET instruction is used to return from a trap in M-mode
* or S-mode, respectively. When executing an xRET instruction, if xPP
* holds the value y, then ELP is set to the value of xPELP if yLPE is
* 1; otherwise, it is set to NO_LP_EXPECTED; xPELP is set to
* NO_LP_EXPECTED.
*/
if haveZicfilp() then {
match zicfilp_xLPE() {
true => { elp = get_MPELP() },
false => { elp = ElpState_to_bits(NO_LP_EXPECTED) }
};
match (sizeof(xlen)) {
32 => {mstatush = update_MPELP(mstatush, ElpState_to_bits(NO_LP_EXPECTED))},
_ => {mstatus = update_mstatus_MPELP(mstatus, ElpState_to_bits(NO_LP_EXPECTED))}
};
}
}
/* extension to SRET */
function zicfilp_set_elp_to_spelp() -> unit = {
/* An MRET or SRET instruction is used to return from a trap in M-mode
* or S-mode, respectively. When executing an xRET instruction, if xPP
* holds the value y, then ELP is set to the value of xPELP if yLPE is
* 1; otherwise, it is set to NO_LP_EXPECTED; xPELP is set to
* NO_LP_EXPECTED.
*/
if haveZicfilp() then {
match zicfilp_xLPE() {
true => { elp = mstatus.SPELP() },
false => { elp = ElpState_to_bits(NO_LP_EXPECTED) }
};
mstatus = update_SPELP(mstatus, ElpState_to_bits(NO_LP_EXPECTED));
}
}
18 changes: 12 additions & 6 deletions model/riscv_insts_zicsr.sail
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ function readCSR csr : csreg -> xlenbits = {
(0x3BE, _) => pmpaddr14,
(0x3BF, _) => pmpaddr15,

(0x747, _) => mseccfg.bits()[(sizeof(xlen) - 1) .. 0], // mseccfg
(0x757, 32) => mseccfg.bits()[63 .. 32], // mseccfgh

/* machine mode counters */
(0xB00, _) => mcycle[(sizeof(xlen) - 1) .. 0],
(0xB02, _) => minstret[(sizeof(xlen) - 1) .. 0],
Expand All @@ -156,7 +159,7 @@ function readCSR csr : csreg -> xlenbits = {
(0x104, _) => lower_mie(mie, mideleg).bits(),
(0x105, _) => get_stvec(),
(0x106, _) => zero_extend(scounteren.bits()),
(0x10A, _) => senvcfg.bits()[sizeof(xlen) - 1 .. 0],
(0x10A, _) => get_senvcfg()[sizeof(xlen) - 1 .. 0],
(0x140, _) => sscratch,
(0x141, _) => get_xret_target(Supervisor) & pc_alignment_mask(),
(0x142, _) => scause.bits(),
Expand Down Expand Up @@ -198,10 +201,10 @@ function writeCSR (csr : csreg, value : xlenbits) -> unit = {
(0x304, _) => { mie = legalize_mie(mie, value); Some(mie.bits()) },
(0x305, _) => { Some(set_mtvec(value)) },
(0x306, _) => { mcounteren = legalize_mcounteren(mcounteren, value); Some(zero_extend(mcounteren.bits())) },
(0x30A, 32) => { menvcfg = legalize_envcfg(menvcfg, menvcfg.bits()[63 .. 32] @ value); Some(menvcfg.bits()[31 .. 0]) },
(0x30A, 64) => { menvcfg = legalize_envcfg(menvcfg, value); Some(menvcfg.bits()) },
(0x310, 32) => { Some(mstatush.bits()) }, // ignore writes for now
(0x31A, 32) => { menvcfg = legalize_envcfg(menvcfg, value @ menvcfg.bits()[31 .. 0]); Some(menvcfg.bits()[63 .. 32]) },
(0x30A, 32) => { menvcfg = legalize_menvcfg(menvcfg, menvcfg.bits()[63 .. 32] @ value); Some(menvcfg.bits()[31 .. 0]) },
(0x30A, 64) => { menvcfg = legalize_menvcfg(menvcfg, value); Some(menvcfg.bits()) },
(0x310, 32) => { mstatush = legalize_mstatush(mstatush, value); Some(mstatush.bits())},
(0x31A, 32) => { menvcfg = legalize_menvcfg(menvcfg, value @ menvcfg.bits()[31 .. 0]); Some(menvcfg.bits()[63 .. 32]) },
(0x320, _) => { mcountinhibit = legalize_mcountinhibit(mcountinhibit, value); Some(zero_extend(mcountinhibit.bits())) },
(0x340, _) => { mscratch = value; Some(mscratch) },
(0x341, _) => { Some(set_xret_target(Machine, value)) },
Expand Down Expand Up @@ -232,6 +235,9 @@ function writeCSR (csr : csreg, value : xlenbits) -> unit = {
(0x3BE, _) => { pmpaddr14 = pmpWriteAddr(pmpLocked(pmp14cfg), pmpTORLocked(pmp15cfg), pmpaddr14, value); Some(pmpaddr14) },
(0x3BF, _) => { pmpaddr15 = pmpWriteAddr(pmpLocked(pmp15cfg), false, pmpaddr15, value); Some(pmpaddr15) },

(0x747, _) => { mseccfg = legalize_mseccfg(mseccfg, value); Some(mseccfg.bits()[sizeof(xlen) - 1 .. 0]) },
(0x757, 32) => { mseccfg = legalize_mseccfg_high(mseccfg, value); Some(mseccfg.bits()[63 .. 32]) },

/* machine mode counters */
(0xB00, _) => { mcycle[(sizeof(xlen) - 1) .. 0] = value; Some(value) },
(0xB02, _) => { minstret[(sizeof(xlen) - 1) .. 0] = value; minstret_increment = false; Some(value) },
Expand All @@ -248,7 +254,7 @@ function writeCSR (csr : csreg, value : xlenbits) -> unit = {
(0x104, _) => { mie = legalize_sie(mie, mideleg, value); Some(mie.bits()) },
(0x105, _) => { Some(set_stvec(value)) },
(0x106, _) => { scounteren = legalize_scounteren(scounteren, value); Some(zero_extend(scounteren.bits())) },
(0x10A, _) => { senvcfg = legalize_envcfg(senvcfg, zero_extend(value)); Some(senvcfg.bits()[sizeof(xlen) - 1 .. 0]) },
(0x10A, _) => { senvcfg = legalize_senvcfg(senvcfg, zero_extend(value)); Some(senvcfg.bits()[sizeof(xlen) - 1 .. 0]) },
(0x140, _) => { sscratch = value; Some(sscratch) },
(0x141, _) => { Some(set_xret_target(Supervisor, value)) },
(0x142, _) => { scause->bits() = value; Some(scause.bits()) },
Expand Down
7 changes: 6 additions & 1 deletion model/riscv_step_ext.sail
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,14 @@

/* The default implementation of hooks for the step() and main() functions. */

/* Zicfilp extension to fetch */
val zicfilp_check_if_lpad : (FetchResult) -> FetchResult

function ext_init() -> unit = ()

function ext_fetch_hook(f : FetchResult) -> FetchResult = f
function ext_fetch_hook(f : FetchResult) -> FetchResult = {
zicfilp_check_if_lpad(f)
}

function ext_pre_step_hook() -> unit = ()
function ext_post_step_hook() -> unit = ()
7 changes: 6 additions & 1 deletion model/riscv_step_rvfi.sail
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,14 @@
/* SUCH DAMAGE. */
/*=======================================================================================*/

/* Zicfilp extension to fetch */
val zicfilp_check_if_lpad : (FetchResult) -> FetchResult

/* Step hooks for rvfi. */

function ext_fetch_hook(f : FetchResult) -> FetchResult = f
function ext_fetch_hook(f : FetchResult) -> FetchResult = {
zicfilp_check_if_lpad(f)
}

function ext_pre_step_hook() -> unit = ()

Expand Down
Loading

0 comments on commit 4d1a435

Please sign in to comment.