Skip to content

Commit

Permalink
Document stack high water mark.
Browse files Browse the repository at this point in the history
Make it explicitly 16-byte aligned and point out the unaligned write spanning mshwmb corner case, which we do not require hardware to handle.

Fixes #15.
  • Loading branch information
ronorton committed Apr 2, 2024
1 parent 1e24f42 commit b89c59c
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 4 deletions.
2 changes: 2 additions & 0 deletions archdoc/chap-changes.tex
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,6 @@ \chapter{Version history}
even if none were ever explicitly constructed.
\end{description}
\end{description}
\item[\ghissue{15}, \ghpr{49}] Document stack high water mark.
Make it explicitly 16-byte aligned and point out the unaligned write spanning \mshwmb{} corner case, which we do not require hardware to handle.
\end{description}
20 changes: 20 additions & 0 deletions archdoc/chap-cheri-riscv.tex
Original file line number Diff line number Diff line change
Expand Up @@ -712,3 +712,23 @@ \section{Instruction compression}
The \cherimcuisa{} introduces changes to mappings between certain compressed and uncompressed instructions, but no changes to the encodings of compressed instructions themselves.
This translates to minimum logic modifications when adding \cherimcuisa{} support to an existing RISC-V CPU.
However, experiments in \cref{chap:c-changes} show that further code size reduction can be achieved by introducing changes in the encoding themselves, to accommodate RV32E and CHERI instructions.

\section{Stack high water mark}
\label{sec:shwm}

The stack high water mark is a simple mechanism in \cherimcu{} to track stack use so that the RTOS switcher implementation can minimise the amount of stack zeroing during compartment calls.
The mechanism uses two new integer CSRs: the stack high water mark, \mshwm{} (\asm{0xBC1}), and the stack high water mark base, \mshwmb{} (\asm{0xBC2}).
These may be read and written using the \asm{CSRRW} instruction only if \PCC{} has \cappermASR{}.
The least significant four bits of both registers are hardwired to zeros, making them 16-byte aligned.
Any write with the hardwired bits set is legalised by rounding down.

On every memory write the address of the write (the lowest byte written) is compared to \mshwm{} and \mshwmb{}.
If the address is greater than or equal to \mshwmb{} and less than \mshwm{} then \mshwm{} is updated with the address of the write (rounded down to 16-byte alignment).
Thus, if \mshwmb{} is set to the stack base and \mshwm{} to some address in the stack region then \mshwm{} will track the lowest stack address written that is less than the original value of \mshwm{}.
Since stacks grow downwards this indicates the maximum stack usage, which is used to optimise stack zeroing.

Note that only the address of the write is accounted for, not the width.
This means that it is possible for an unaligned write with an address below \mshwmb{} to write bytes above \mshwmb{} without updating \mshwm{}.
For example a 4-byte write to \mshwmb{}$ - 1$ would write the bytes at \mshwmb{}$\dots{}$\mshwmb$+ 2$, but leave \mshwm{} unchanged.
This is not a problem for the RTOS's use case as the RTOS will never issue a capability that crosses the stack base to untrusted code.
Given this, we choose not to unnecessarily complicate the hardware by requiring it to handle this corner case.
2 changes: 2 additions & 0 deletions archdoc/preamble.tex
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,8 @@
\newcommand{\mccsr}{\texttt{mccsr}}
\newcommand{\sccsr}{\texttt{sccsr}}
\newcommand{\uccsr}{\texttt{uccsr}}
\newcommand{\mshwm}{\texttt{mshwm}}
\newcommand{\mshwmb}{\texttt{mshwmb}}
% RISC-V existing registers
\newcommand{\xtval}{\texttt{{\it x}tval}}
\newcommand{\xtvec}{\texttt{{\it x}tvec}}
Expand Down
6 changes: 4 additions & 2 deletions src/cheri_addr_checks.sail
Original file line number Diff line number Diff line change
Expand Up @@ -206,9 +206,11 @@ function ext_check_phys_mem_read (access_type, paddr, size, aquire, release, res

function ext_check_phys_mem_write(write_kind, paddr, size, data, metadata) = {
if ((paddr >=_u MSHWMB) & (paddr <_u MSHWM)) then {
/* align down MSHWM to 16 bytes */
paddr16 = legalize_mshwm(paddr);
if get_config_print_reg()
then print_reg("MSHWM <- " ^ BitStr(paddr));
MSHWM = paddr;
then print_reg("MSHWM <- " ^ BitStr(paddr16));
MSHWM = paddr16;
};
Ext_PhysAddr_OK()
}
Expand Down
13 changes: 11 additions & 2 deletions src/cheri_sys_regs.sail
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,15 @@ function legalize_ccsr(c : ccsr, v : xlenbits) -> ccsr = {
c
}

/*!
* Legalize stack high water mark by rounding
* down to 16-byte aligned value.
*/
function legalize_mshwm(v : xlenbits) -> xlenbits = {
[v with 3..0=0x0]
}
overload legalize_mshwmb = {legalize_mshwm}

// XXX these are currently disabled due to sail bug when compiling C
//mapping clause csr_name_map = 0x8c0 <-> "uccsr"
//mapping clause csr_name_map = 0x9c0 <-> "sccsr"
Expand All @@ -107,8 +116,8 @@ function clause ext_write_CSR (0x8C0, value) = { uccsr = legalize_ccsr(uccsr, va
function clause ext_write_CSR (0x9C0, value) = { sccsr = legalize_ccsr(sccsr, value); Some(sccsr.bits()) }
function clause ext_write_CSR (0xBC0, value) = { mccsr = legalize_ccsr(mccsr, value); Some(mccsr.bits()) }

function clause ext_write_CSR (0xBC1, value) = { MSHWM = value; Some(value) }
function clause ext_write_CSR (0xBC2, value) = { MSHWMB = value; Some(value) }
function clause ext_write_CSR (0xBC1, value) = { MSHWM = legalize_mshwm(value); Some(MSHWM) }
function clause ext_write_CSR (0xBC2, value) = { MSHWMB = legalize_mshwmb(value); Some(MSHWMB) }

function clause ext_is_CSR_defined (0x8C0, p) = haveUsrMode() // uccsr
function clause ext_is_CSR_defined (0x9C0, p) = haveSupMode() & (p == Machine | p == Supervisor) // sccsr
Expand Down

0 comments on commit b89c59c

Please sign in to comment.