Merge pull request #8 from CTSRD-CHERI/wip-aj443-getMeta
Introduced a getMeta method as a counterpart to getAddr for getting all
This commit is contained in:
@@ -92,6 +92,7 @@ typedef `FLAGSW FlagsW;
|
||||
typedef 64 CapAddrW;
|
||||
typedef 128 CapW;
|
||||
`endif
|
||||
|
||||
// The Address type is used to represent the full sized address returned to the
|
||||
// consuming pipeline. In cases where fewer than CapAddrW bits are stored to
|
||||
// represent a memory address (and remaining bits are usable for storing extra
|
||||
@@ -145,7 +146,7 @@ typedef struct {
|
||||
Bit#(OTypeW) otype;
|
||||
CBounds bounds;
|
||||
CapAddr address;
|
||||
} CapabilityInMemory deriving(Bits, Eq, FShow); // CapW + 1 (tag bit)
|
||||
} CapabilityInMemory deriving (Bits, Eq, FShow); // CapW + 1 (tag bit)
|
||||
// The full capability structure as Bits, including the "tag" bit.
|
||||
typedef Bit#(TAdd#(CapW,1)) Capability;
|
||||
// not including the tag bit
|
||||
@@ -180,7 +181,7 @@ typedef struct {
|
||||
Bit#(OTypeW) otype;
|
||||
Format format;
|
||||
Bounds bounds;
|
||||
} CapFat deriving(Bits);
|
||||
} CapFat deriving (Bits);
|
||||
|
||||
// "Architectural FShow"
|
||||
function Fmt showArchitectural(CapFat cap) =
|
||||
@@ -847,7 +848,7 @@ typedef struct {
|
||||
TempFields tempFields;
|
||||
} CapPipe deriving (Bits);
|
||||
|
||||
instance CHERICap #(CapMem, OTypeW, FlagsW, CapAddrW, CapW, TSub#(MW, 3));
|
||||
instance CHERICap #(CapMem, OTypeW, FlagsW, CapAddrW, CapW, TSub #(MW, 3));
|
||||
function isValidCap (capMem);
|
||||
CapabilityInMemory cap = unpack(capMem);
|
||||
return cap.isCapability;
|
||||
@@ -887,9 +888,17 @@ instance CHERICap #(CapMem, OTypeW, FlagsW, CapAddrW, CapW, TSub#(MW, 3));
|
||||
function setSoftPerms = error("setSoftPerms not implemented for CapMem");
|
||||
function getKind = error("getKind not implemented for CapMem");
|
||||
function setKind = error("setKind not implemented for CapMem");
|
||||
function getMeta(capMem);
|
||||
CapabilityInMemory cap = unpack(capMem);
|
||||
return { pack (cap.perms)
|
||||
, pack (cap.reserved)
|
||||
, pack (cap.flags)
|
||||
, pack (cap.otype)
|
||||
, pack (cap.bounds) };
|
||||
endfunction
|
||||
function getAddr(capMem);
|
||||
CapabilityInMemory cap = unpack(capMem);
|
||||
return cap.address;
|
||||
return pack (cap.address);
|
||||
endfunction
|
||||
function setAddr = error("setAddr not implemented for CapMem");
|
||||
function setAddrUnsafe (capMem, address);
|
||||
@@ -946,7 +955,7 @@ instance Eq #(CapReg);
|
||||
// function Bool \/= (CapPipe x, CapPipe y);
|
||||
endinstance
|
||||
|
||||
instance CHERICap #(CapReg, OTypeW, FlagsW, CapAddrW, CapW, TSub#(MW, 3));
|
||||
instance CHERICap #(CapReg, OTypeW, FlagsW, CapAddrW, CapW, TSub #(MW, 3));
|
||||
|
||||
function isValidCap (x) = x.isCapability;
|
||||
|
||||
@@ -1016,7 +1025,15 @@ instance CHERICap #(CapReg, OTypeW, FlagsW, CapAddrW, CapW, TSub#(MW, 3));
|
||||
tagged SEALED_WITH_TYPE .ot: seal(cap, ?, VnD {v: True, d:ot});
|
||||
endcase;
|
||||
|
||||
function getAddr (cap) = cap.address;
|
||||
function getMeta(capReg);
|
||||
CapMem cap = unpack (pack (toMem (capReg)));
|
||||
return getMeta (cap);
|
||||
endfunction
|
||||
|
||||
function getAddr (capReg);
|
||||
CapMem cap = unpack (pack (toMem (capReg)));
|
||||
return getAddr (cap);
|
||||
endfunction
|
||||
|
||||
function setAddr = error("setAddr not implemented for CapReg");
|
||||
|
||||
@@ -1091,7 +1108,9 @@ instance CHERICap #(CapPipe, OTypeW, FlagsW, CapAddrW, CapW, TSub#(MW, 3));
|
||||
function setKind (cap, kind) =
|
||||
CapPipe { capFat:setKind(cap.capFat,kind)
|
||||
, tempFields: cap.tempFields };
|
||||
function getAddr (cap) = getAddr(cap.capFat);
|
||||
|
||||
function getMeta (cap) = getMeta (cap.capFat);
|
||||
function getAddr (cap) = getAddr (cap.capFat);
|
||||
function maskAddr (cap, mask) =
|
||||
CapPipe { capFat: maskAddr(cap.capFat, mask)
|
||||
, tempFields: cap.tempFields };
|
||||
|
||||
100
CHERICap.bsv
100
CHERICap.bsv
@@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2018-2019 Alexandre Joannou
|
||||
* Copyright (c) 2018-2021 Alexandre Joannou
|
||||
* Copyright (c) 2019 Peter Rugg
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -29,27 +29,29 @@
|
||||
|
||||
package CHERICap;
|
||||
|
||||
// CHERI capability typeclass
|
||||
// CHERI public types
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Permission bits
|
||||
|
||||
typedef Bit#(16) SoftPerms;
|
||||
typedef Bit #(16) SoftPerms;
|
||||
|
||||
typedef struct {
|
||||
Bool permitSetCID;
|
||||
Bool accessSysRegs;
|
||||
Bool permitUnseal;
|
||||
Bool permitCCall;
|
||||
Bool permitSeal;
|
||||
Bool permitStoreLocalCap;
|
||||
Bool permitStoreCap;
|
||||
Bool permitLoadCap;
|
||||
Bool permitStore;
|
||||
Bool permitLoad;
|
||||
Bool permitExecute;
|
||||
Bool global;
|
||||
Bool permitSetCID;
|
||||
Bool accessSysRegs;
|
||||
Bool permitUnseal;
|
||||
Bool permitCCall;
|
||||
Bool permitSeal;
|
||||
Bool permitStoreLocalCap;
|
||||
Bool permitStoreCap;
|
||||
Bool permitLoadCap;
|
||||
Bool permitStore;
|
||||
Bool permitLoad;
|
||||
Bool permitExecute;
|
||||
Bool global;
|
||||
} HardPerms deriving(Bits, Eq, FShow);
|
||||
|
||||
instance Bitwise#(HardPerms);
|
||||
instance Bitwise #(HardPerms);
|
||||
function \& (x1, x2) = unpack(pack(x1) & pack(x2));
|
||||
function \| (x1, x2) = unpack(pack(x1) | pack(x2));
|
||||
function \^ (x1, x2) = unpack(pack(x1) ^ pack(x2));
|
||||
@@ -62,31 +64,45 @@ instance Bitwise#(HardPerms);
|
||||
function lsb (x) = lsb(pack(x));
|
||||
endinstance
|
||||
|
||||
// Type to return the result of an operation along with whether the operation was exact
|
||||
// In cases where no sensible inexact representation exists, the only guarantee is that
|
||||
// the tag bit is not set.
|
||||
// Helper type to return the result of an operation along with whether the
|
||||
// operation was exact. In cases where no sensible inexact representation
|
||||
// exists, the only guarantee is that the tag bit is not set.
|
||||
|
||||
typedef struct {
|
||||
Bool exact;
|
||||
t value;
|
||||
} Exact #(type t) deriving (Bits);
|
||||
|
||||
// Kind of a capability, that is whether it is "sealed with a given otype", or
|
||||
// if it is a "sentry" or simply "unsealed".
|
||||
|
||||
typedef union tagged {
|
||||
void UNSEALED;
|
||||
void SENTRY;
|
||||
void RES0;
|
||||
void RES1;
|
||||
Bit#(ot) SEALED_WITH_TYPE;
|
||||
} Kind#(numeric type ot) deriving (Bits, Eq, FShow);
|
||||
Bit #(ot) SEALED_WITH_TYPE;
|
||||
} Kind #(numeric type ot) deriving (Bits, Eq, FShow);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// Helper type for the return value of the 'setBoundsCombined' method
|
||||
|
||||
typedef struct {
|
||||
t cap;
|
||||
Bool exact;
|
||||
Bit#(n) length;
|
||||
Bit#(n) mask;
|
||||
} SetBoundsReturn#(type t, numeric type n) deriving (Bits, Eq, FShow);
|
||||
Bit #(n) length;
|
||||
Bit #(n) mask;
|
||||
} SetBoundsReturn #(type t, numeric type n) deriving (Bits, Eq, FShow);
|
||||
|
||||
typeclass CHERICap#(type t, numeric type ot, numeric type flg, numeric type n, numeric type mem_sz, numeric type maskable_bits)
|
||||
|
||||
// CHERI capability typeclass
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typeclass CHERICap #( type t
|
||||
, numeric type ot
|
||||
, numeric type flg
|
||||
, numeric type n
|
||||
, numeric type mem_sz
|
||||
, numeric type maskable_bits )
|
||||
dependencies (t determines (ot, flg, n, mem_sz, maskable_bits));
|
||||
|
||||
// Return whether the Capability is valid
|
||||
@@ -112,14 +128,22 @@ typeclass CHERICap#(type t, numeric type ot, numeric type flg, numeric type n, n
|
||||
zeroExtend({pack(getSoftPerms(cap)), 3'h0, pack(getHardPerms(cap))});
|
||||
// Set the architectural permissions
|
||||
function t setPerms (t cap, Bit#(31) perms) =
|
||||
setSoftPerms(setHardPerms(cap, unpack(perms[11:0])), unpack(truncate(perms[30:15])));
|
||||
setSoftPerms ( setHardPerms(cap, unpack(perms[11:0]))
|
||||
, unpack(truncate(perms[30:15])) );
|
||||
|
||||
// Manipulate the kind of the capability, i.e. whether it is sealed, sentry, unsealed, ...
|
||||
// Manipulate the kind of the capability, i.e. whether it is sealed, sentry,
|
||||
// unsealed, ...
|
||||
function Kind#(ot) getKind (t cap);
|
||||
function t setKind (t cap, Kind#(ot) kind);
|
||||
|
||||
// Get the address pointed to by the capability
|
||||
function Bit#(n) getAddr (t cap);
|
||||
// Get the in-memory architectural representation of the capability metadata
|
||||
function Bit #(TSub #(mem_sz, n)) getMeta (t cap);
|
||||
// Get the in-memory architectural representation of the capability address
|
||||
function Bit #(n) getAddr (t cap);
|
||||
|
||||
// Note that the following rule is expected to hold:
|
||||
// fromMem (tuple2 (isValidCap (cap), {getMeta (cap), getAddr (cap)})) == cap
|
||||
|
||||
// Set the address of the capability. Result invalid if unrepresentable
|
||||
function Exact#(t) setAddr (t cap, Bit#(n) addr);
|
||||
// Set the address of the capability. Result assumed to be representable
|
||||
@@ -153,7 +177,8 @@ typeclass CHERICap#(type t, numeric type ot, numeric type flg, numeric type n, n
|
||||
return isNotTooLow && isNotTooHigh;
|
||||
endfunction
|
||||
|
||||
// Set the length of the capability. Inexact: result length may be different to requested
|
||||
// Set the length of the capability. Inexact: result length may be different
|
||||
// to requested
|
||||
function Exact#(t) setBounds (t cap, Bit#(n) length);
|
||||
let combinedResult = setBoundsCombined(cap, length);
|
||||
return Exact {exact: combinedResult.exact, value: combinedResult.cap};
|
||||
@@ -175,7 +200,7 @@ typeclass CHERICap#(type t, numeric type ot, numeric type flg, numeric type n, n
|
||||
// Check if a type is valid
|
||||
function Bool validAsType (t dummy, Bit#(n) checkType);
|
||||
|
||||
// convert from and to bit memory representation
|
||||
// Convert from and to bit memory representation
|
||||
function t fromMem (Tuple2#(Bool, Bit#(mem_sz)) mem_cap);
|
||||
function Tuple2#(Bool, Bit#(mem_sz)) toMem (t cap);
|
||||
|
||||
@@ -192,7 +217,8 @@ typeclass CHERICap#(type t, numeric type ot, numeric type flg, numeric type n, n
|
||||
function Bit#(2) getBaseAlignment (t cap);
|
||||
|
||||
// Get representable alignment mask
|
||||
function Bit#(n) getRepresentableAlignmentMask (t dummy, Bit#(n) length_request) =
|
||||
function Bit#(n) getRepresentableAlignmentMask ( t dummy
|
||||
, Bit#(n) length_request) =
|
||||
setBoundsCombined(nullCapFromDummy(dummy), length_request).mask;
|
||||
|
||||
// Get representable length
|
||||
@@ -204,7 +230,8 @@ typeclass CHERICap#(type t, numeric type ot, numeric type flg, numeric type n, n
|
||||
|
||||
endtypeclass
|
||||
|
||||
function Fmt showCHERICap(t cap) provisos (CHERICap#(t, ot, flg, n, mem_sz, maskable_bits));
|
||||
function Fmt showCHERICap (t cap)
|
||||
provisos (CHERICap #(t , ot, flg, n, mem_sz, maskable_bits));
|
||||
return $format( "Valid: 0x%0x", isValidCap(cap)) +
|
||||
$format(" Perms: 0x%0x", getPerms(cap)) +
|
||||
$format(" Kind: ", fshow(getKind(cap))) +
|
||||
@@ -213,6 +240,9 @@ function Fmt showCHERICap(t cap) provisos (CHERICap#(t, ot, flg, n, mem_sz, mask
|
||||
$format(" Length: 0x%0x", getLength(cap));
|
||||
endfunction
|
||||
|
||||
// Cast typeclass to convert from one type to another. Helpful for converting
|
||||
// a capability format to another.
|
||||
|
||||
typeclass Cast#(type src, type dest);
|
||||
function dest cast (src x);
|
||||
endtypeclass
|
||||
|
||||
Reference in New Issue
Block a user