summaryrefslogtreecommitdiff
path: root/cheri/cheri_prelude_128.sail
diff options
context:
space:
mode:
Diffstat (limited to 'cheri/cheri_prelude_128.sail')
-rw-r--r--cheri/cheri_prelude_128.sail331
1 files changed, 0 insertions, 331 deletions
diff --git a/cheri/cheri_prelude_128.sail b/cheri/cheri_prelude_128.sail
deleted file mode 100644
index da761c91..00000000
--- a/cheri/cheri_prelude_128.sail
+++ /dev/null
@@ -1,331 +0,0 @@
-/*========================================================================*/
-/* */
-/* Copyright (c) 2015-2017 Robert M. Norton */
-/* Copyright (c) 2015-2017 Kathyrn Gray */
-/* All rights reserved. */
-/* */
-/* This software was developed by the University of Cambridge Computer */
-/* Laboratory as part of the Rigorous Engineering of Mainstream Systems */
-/* (REMS) project, funded by EPSRC grant EP/K008528/1. */
-/* */
-/* 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. */
-/*========================================================================*/
-
-/* 128 bit cap + tag */
-type CapReg = bits(129)
-
-struct CapStruct = {
- tag : bool ,
- uperms : bits(4) ,
- access_system_regs : bool ,
- permit_unseal : bool ,
- permit_ccall : bool ,
- permit_seal : bool ,
- permit_store_local_cap : bool ,
- permit_store_cap : bool ,
- permit_load_cap : bool ,
- permit_store : bool ,
- permit_load : bool ,
- permit_execute : bool ,
- global : bool ,
- reserved : bits(2) ,
- E : bits(6) ,
- sealed : bool ,
- B : bits(20),
- T : bits(20),
- otype : bits(24),
- address : bits(64)
-}
-
-let null_cap : CapStruct = struct {
- tag = false,
- uperms = zeros(),
- access_system_regs = false,
- permit_unseal = false,
- permit_ccall = false,
- permit_seal = false,
- permit_store_local_cap = false,
- permit_store_cap = false,
- permit_load_cap = false,
- permit_store = false,
- permit_load = false,
- permit_execute = false,
- global = false,
- reserved = zeros(),
- E = 0b110000, /* 48, encoded as 0 in memory due to xor */
- sealed = false,
- B = zeros(),
- T = 0x10000,
- otype = zeros(),
- address = zeros()
-}
-
-let default_cap : CapStruct = struct {
- tag = true,
- uperms = ones(),
- access_system_regs = true,
- permit_unseal = true,
- permit_ccall = true,
- permit_seal = true,
- permit_store_local_cap = true,
- permit_store_cap = true,
- permit_load_cap = true,
- permit_store = true,
- permit_load = true,
- permit_execute = true,
- global = true,
- reserved = zeros(),
- E = 0b110000, /* 48, encoded as 0 in memory due to xor */
- sealed = false,
- B = zeros(),
- T = 0x10000,
- otype = zeros(),
- address = zeros()
-}
-
-let 'cap_size = 16
-
-function capRegToCapStruct(c) : CapReg -> CapStruct =
- let s : bool = c[104] in
- let Bc : bits(20) = if s then c[103..96] @ 0x000 else c[103..84] in
- let Tc : bits(20) = if s then c[83..76] @ 0x000 else c[83..64] in
- let otype : bits(24) = if s then c[95..84] @ c[75..64] else zeros() in
- struct {
- tag = c[128],
- uperms = c[127..124],
- access_system_regs = c[123],
- permit_unseal = c[122],
- permit_ccall = c[121],
- permit_seal = c[120],
- permit_store_local_cap = c[119],
- permit_store_cap = c[118],
- permit_load_cap = c[117],
- permit_store = c[116],
- permit_load = c[115],
- permit_execute = c[114],
- global = c[113],
- reserved = c[112..111],
- E = c[110..105],
- sealed = s,
- B = Bc,
- T = Tc,
- otype = otype,
- address = c[63..0]
- }
-
-function getCapHardPerms(cap) : CapStruct -> bits(11) =
- (cap.access_system_regs
- @ cap.permit_unseal
- @ cap.permit_ccall
- @ cap.permit_seal
- @ cap.permit_store_local_cap
- @ cap.permit_store_cap
- @ cap.permit_load_cap
- @ cap.permit_store
- @ cap.permit_load
- @ cap.permit_execute
- @ cap.global)
-
-function capStructToMemBits128(cap) : CapStruct -> bits(128) =
- let b : bits(20) = if cap.sealed then (cap.B)[19..12] @ (cap.otype)[23..12] else cap.B in
- let t : bits(20) = if cap.sealed then (cap.T)[19..12] @ (cap.otype)[11..0] else cap.T in
- ( cap.uperms
- @ getCapHardPerms(cap)
- @ cap.reserved
- @ cap.E
- @ cap.sealed
- @ b
- @ t
- @ cap.address
- )
-
-function capStructToCapReg(cap) : CapStruct -> CapReg =
- (cap.tag @ capStructToMemBits128(cap))
-
-/* Reverse of above used when reading from memory */
-function memBitsToCapBits128(tag, b) : (bool, bits(128)) -> CapReg=
- (tag @ b)
-
-/* When saving/restoring capabilities xor them with bits of null_cap --
- this ensures that canonical null_cap is always all-zeros in memory
- even though it may have bits set logically (e.g. length or exponent */
-
-let null_cap_bits : bits(128) = capStructToMemBits128(null_cap)
-
-function capStructToMemBits(cap) : CapStruct -> bits(128) =
- capStructToMemBits128(cap) ^ null_cap_bits
-
-function memBitsToCapBits(tag, b) : (bool, bits(128)) -> bits(129) =
- memBitsToCapBits128(tag, b ^ null_cap_bits)
-
-function getCapPerms(cap) : CapStruct -> bits(31) =
- let perms : bits(15) = zero_extend(getCapHardPerms(cap)) in
- (0x000 /* uperms 30-19 */
- @ cap.uperms
- @ perms)
-
-function setCapPerms(cap, perms) : (CapStruct, bits(31)) -> CapStruct =
- { cap with
- uperms = perms[18..15],
- /* 14..11 reserved -- ignore */
- access_system_regs = perms[10],
- permit_unseal = perms[9],
- permit_ccall = perms[8],
- permit_seal = perms[7],
- permit_store_local_cap = perms[6],
- permit_store_cap = perms[5],
- permit_load_cap = perms[4],
- permit_store = perms[3],
- permit_load = perms[2],
- permit_execute = perms[1],
- global = perms[0]
- }
-
-function sealCap(cap, otype) : (CapStruct, bits(24)) -> (bool, CapStruct) =
- if (((cap.T)[11..0] == zeros()) & ((cap.B)[11..0] == zeros())) then
- (true, {cap with sealed=true, otype=otype})
- else
- (false, cap /* XXX should be undefined? */ )
-
-function a_top_correction(a_mid, R, bound) : (bits(20), bits(20), bits(20)) -> bits(65) =
- match (a_mid <_u R, bound <_u R) {
- (false, false) => zeros(),
- (false, true) => zero_extend(0b1),
- (true, false) => ones(),
- (true, true) => zeros()
- }
-
-function getCapBase(c) : CapStruct -> uint64 =
- let E = min(unsigned(c.E), 48) in
- let Bc : bits(20) = c.B in
- let a : bits(65) = zero_extend(c.address) in
- let R : bits(20) = Bc - 0x01000 in /* wraps */
- let a_mid : bits(20) = mask(a >> E) in
- let correction = a_top_correction(a_mid, R, Bc) in
- let a_top = a >> E+20 in
- let base : bits(64) = mask(((a_top + correction) @ Bc) << E) in
- unsigned(base)
-
-function getCapTop (c) : CapStruct -> CapLen =
- let E = min(unsigned(c.E), 48) in
- let Bc : bits(20) = c.B in
- let T : bits(20) = c.T in
- let a : bits(65) = zero_extend(c.address) in
- let R : bits(20) = Bc - 0x01000 in /* wraps */
- let a_mid : bits(20) = mask(a >> E) in
- let correction = a_top_correction(a_mid, R, T) in
- let a_top = a >> E+20 in
- let top1 : bits(65) = mask((a_top + correction) @ T) in
- unsigned(top1 << E)
-
-function getCapOffset(c) : CapStruct -> uint64 =
- let base = getCapBase(c) in
- (unsigned(c.address) - base) % pow2(64)
-
-function getCapLength(c) : CapStruct -> CapLen =
- let 'top = getCapTop(c) in
- let 'base = getCapBase(c) in {
- assert (top >= base);
- top - base
- }
-
-function getCapCursor(cap) : CapStruct -> uint64 = unsigned(cap.address)
-
-function fastRepCheck(c, i) : (CapStruct, bits(64)) -> bool=
- let 'E = unsigned(c.E) in
- if (E >= 44) then
- true /* in this case representable region is whole address space */
- else
- let E' = min(E, 43) in
- let i_top = signed(i[63..E+20]) in
- let i_mid : bits(20) = i[E+19..E] in
- let a_mid : bits(20) = (c.address)[E+19..E] in
- let R : bits(20) = (c.B) - 0x01000 in
- let diff : bits(20) = R - a_mid in
- let diff1 : bits(20) = diff - 1 in
- /* i_top determines 1. whether the increment is inRange
- i.e. less than the size of the representable region
- (2**(E+20)) and 2. whether it is positive or negative. To
- satisfy 1. all top bits must be the same so we are
- interested in the cases i_top is 0 or -1 */
- if (i_top == 0) then
- i_mid <_u diff1
- else if (i_top == -1) then
- (i_mid >=_u diff) & (R != a_mid)
- else
- false
-
-function setCapOffset(c, offset) : (CapStruct, bits(64)) -> (bool, CapStruct) =
- let base : bits(64) = to_bits(64, getCapBase(c)) in
- let newAddress : bits(64) = base + offset in
- let newCap = { c with address = newAddress } in
- let representable = fastRepCheck(c, (newAddress - c.address)) in
- (representable, newCap)
-
-function incCapOffset(c, delta) : (CapStruct, bits(64)) -> (bool, CapStruct) =
- let newAddress : bits(64) = c.address + delta in
- let newCap = { c with address = newAddress } in
- let representable = fastRepCheck(c, delta) in
- (representable, newCap)
-
-/** FUNCTION:integer HighestSetBit(bits(N) x) */
-
-val HighestSetBit : forall 'N , 'N >= 2. bits('N) -> {'n, 0 <= 'n < 'N . (bool, atom('n))}
-function HighestSetBit x = {
- foreach (i from ('N - 1) to 0 by 1 in dec)
- if [x[i]] == 0b1 then return (true, i);
- return (false, 0)
-}
-
-/* hw rounds up E to multiple of 4 */
-function roundUp(e) : range(0, 45) -> range(0, 48) =
- let 'r = e % 4 in
- if (r == 0)
- then e
- else (e - r + 4)
-
-function computeE (rlength) : bits(65) -> range(0, 48) =
- let (nonzero, 'msb) = HighestSetBit((rlength + (rlength >> 6)) >> 19) in
- if nonzero then
- /* above will always return <= 45 because 19 bits of zero are shifted in from right */
- {assert(0 <= msb & msb <= 45); roundUp (min(msb,45)) }
- else
- 0
-
-function setCapBounds(cap, base, top) : (CapStruct, bits(64), bits(65)) -> (bool, CapStruct) =
- /* {cap with base=base; length=(bits(64)) length; offset=0} */
- let 'e = computeE(top - (0b0 @ base)) in
- let Bc : bits(20) = mask(base >> e) in
- let T : bits(20) = mask(top >> e) in
- let e_mask : bits(65) = zero_extend(replicate_bits(0b1, e)) in
- let e_bits = top & e_mask in
- let T2 : bits(20) = T + (if unsigned(e_bits) == 0 then 0x00000 else 0x00001) in
- let newCap = {cap with address=base, E=to_bits(6, e), B=Bc, T=T2} in
- let newBase = getCapBase(newCap) in
- let newTop = getCapTop(newCap) in
- let exact = (unsigned(base) == newBase) & (unsigned(top) == newTop) in
- (exact, newCap)
-
-function int_to_cap (offset) : bits(64) -> CapStruct =
- {null_cap with address = offset}