Refactor to allow some operations on CapReg
This commit is contained in:
286
CHERICC_Fat.bsv
286
CHERICC_Fat.bsv
@@ -335,7 +335,7 @@ function LCapAddress regToSignedLAddr(Address in);
|
|||||||
return signExtend(retVal);
|
return signExtend(retVal);
|
||||||
endfunction
|
endfunction
|
||||||
function Bool isSealed(CapFat cap) = (cap.otype != otype_unsealed);
|
function Bool isSealed(CapFat cap) = (cap.otype != otype_unsealed);
|
||||||
function CType getType(CapFat cap) = VnD{v: (cap.otype != otype_unsealed), d: cap.otype};
|
function CType getTypeFat(CapFat cap) = VnD{v: (cap.otype != otype_unsealed), d: cap.otype};
|
||||||
function Bit#(31) getPerms(CapFat cap);
|
function Bit#(31) getPerms(CapFat cap);
|
||||||
Bit#(SizeOf#(HPerms)) hardPerms = zeroExtend(pack(cap.perms.hard));
|
Bit#(SizeOf#(HPerms)) hardPerms = zeroExtend(pack(cap.perms.hard));
|
||||||
Bit#(UPermW) softPerms = zeroExtend(pack(cap.perms.soft));
|
Bit#(UPermW) softPerms = zeroExtend(pack(cap.perms.soft));
|
||||||
@@ -381,7 +381,7 @@ endfunction
|
|||||||
|
|
||||||
function Bool boundsCheck(CapFat cap, Bit#(CapAddressW) off, TempFields tf);
|
function Bool boundsCheck(CapFat cap, Bit#(CapAddressW) off, TempFields tf);
|
||||||
Bit#(TAdd#(CapAddressW,2)) bo = zeroExtend(off);
|
Bit#(TAdd#(CapAddressW,2)) bo = zeroExtend(off);
|
||||||
cap = incOffset(cap, cap.address+truncate(bo), off, tf, False).d;
|
cap = incOffsetFat(cap, cap.address+truncate(bo), off, tf, False).d;
|
||||||
return cap.isCapability && capInBounds(cap, tf, False);
|
return cap.isCapability && capInBounds(cap, tf, False);
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
@@ -416,13 +416,13 @@ function Tuple2#(CapFat, Bool) setBoundsFat(CapFat cap, Address lengthFull);
|
|||||||
CapAddress tmpAddr = truncate(cap.address);
|
CapAddress tmpAddr = truncate(cap.address);
|
||||||
LCapAddress base = zeroExtend(tmpAddr);
|
LCapAddress base = zeroExtend(tmpAddr);
|
||||||
Bit#(TAdd#(MW,1)) newBaseBits = truncate(base>>e);
|
Bit#(TAdd#(MW,1)) newBaseBits = truncate(base>>e);
|
||||||
|
|
||||||
// Derive new top bits by extracting MW bits from the capability
|
// Derive new top bits by extracting MW bits from the capability
|
||||||
// address + requested length, starting at the new exponent's position,
|
// address + requested length, starting at the new exponent's position,
|
||||||
// and rounding up if significant bits are lost in the process.
|
// and rounding up if significant bits are lost in the process.
|
||||||
LCapAddress len = zeroExtend(length);
|
LCapAddress len = zeroExtend(length);
|
||||||
LCapAddress top = base + len;
|
LCapAddress top = base + len;
|
||||||
|
|
||||||
// Create a mask with all bits set below the MSB of length and then masking all bits
|
// Create a mask with all bits set below the MSB of length and then masking all bits
|
||||||
// below the mantissa bits.
|
// below the mantissa bits.
|
||||||
LCapAddress lmask = smearMSBRight(len);
|
LCapAddress lmask = smearMSBRight(len);
|
||||||
@@ -430,7 +430,7 @@ function Tuple2#(CapFat, Bool) setBoundsFat(CapFat cap, Address lengthFull);
|
|||||||
// The shift amount required to put the most significant set bit of the
|
// The shift amount required to put the most significant set bit of the
|
||||||
// len just above the bottom HalfExpW bits that are taken by the exp.
|
// len just above the bottom HalfExpW bits that are taken by the exp.
|
||||||
Integer shiftAmount = valueOf(TSub#(TSub#(MW,2),HalfExpW));
|
Integer shiftAmount = valueOf(TSub#(TSub#(MW,2),HalfExpW));
|
||||||
|
|
||||||
// Calculate all values associated with E=e (e not rounding up)
|
// Calculate all values associated with E=e (e not rounding up)
|
||||||
// Round up considering the stolen HalfExpW exponent bits if required
|
// Round up considering the stolen HalfExpW exponent bits if required
|
||||||
Bit#(TAdd#(MW,1)) newTopBits = truncate(top>>e);
|
Bit#(TAdd#(MW,1)) newTopBits = truncate(top>>e);
|
||||||
@@ -449,7 +449,7 @@ function Tuple2#(CapFat, Bool) setBoundsFat(CapFat cap, Address lengthFull);
|
|||||||
Bool lostSignificantBase = (base&lmaskLo)!=0 && intExp;
|
Bool lostSignificantBase = (base&lmaskLo)!=0 && intExp;
|
||||||
// If either base or top lost significant bits and we wanted an exact setBounds,
|
// If either base or top lost significant bits and we wanted an exact setBounds,
|
||||||
// void the return capability
|
// void the return capability
|
||||||
|
|
||||||
// Calculate all values associated with E=e+1 (e rounding up due to msb of L increasing by 1)
|
// Calculate all values associated with E=e+1 (e rounding up due to msb of L increasing by 1)
|
||||||
// This value is just to avoid adding later.
|
// This value is just to avoid adding later.
|
||||||
Bit#(MW) newTopBitsHigher = truncateLSB(newTopBits);
|
Bit#(MW) newTopBitsHigher = truncateLSB(newTopBits);
|
||||||
@@ -464,8 +464,8 @@ function Tuple2#(CapFat, Bool) setBoundsFat(CapFat cap, Address lengthFull);
|
|||||||
Bool lostSignificantBaseHigher = (base&lmaskLo)!=0 && intExp;
|
Bool lostSignificantBaseHigher = (base&lmaskLo)!=0 && intExp;
|
||||||
// If either base or top lost significant bits and we wanted an exact setBounds,
|
// If either base or top lost significant bits and we wanted an exact setBounds,
|
||||||
// void the return capability
|
// void the return capability
|
||||||
|
|
||||||
|
|
||||||
// We need to round up Exp if the length is within 1 of the maximum and if it will increase.
|
// We need to round up Exp if the length is within 1 of the maximum and if it will increase.
|
||||||
// The lomask for checking for potential overflow should mask all but the bottom bit of the mantissa.
|
// The lomask for checking for potential overflow should mask all but the bottom bit of the mantissa.
|
||||||
lmaskLo = lmask>>fromInteger(shiftAmount);
|
lmaskLo = lmask>>fromInteger(shiftAmount);
|
||||||
@@ -481,8 +481,8 @@ function Tuple2#(CapFat, Bool) setBoundsFat(CapFat cap, Address lengthFull);
|
|||||||
ret.bounds.baseBits = truncate(newBaseBits);
|
ret.bounds.baseBits = truncate(newBaseBits);
|
||||||
if (lostSignificantBase || lostSignificantTop) resultExact = False;
|
if (lostSignificantBase || lostSignificantTop) resultExact = False;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
ret.bounds.exp = e;
|
ret.bounds.exp = e;
|
||||||
// Update the addrBits fields
|
// Update the addrBits fields
|
||||||
ret.addrBits = ret.bounds.baseBits;
|
ret.addrBits = ret.bounds.baseBits;
|
||||||
@@ -496,7 +496,7 @@ function Tuple2#(CapFat, Bool) setBoundsFat(CapFat cap, Address lengthFull);
|
|||||||
ret.bounds.baseBits = {truncateLSB(ret.bounds.baseBits), botZeroes};
|
ret.bounds.baseBits = {truncateLSB(ret.bounds.baseBits), botZeroes};
|
||||||
ret.bounds.topBits = {truncateLSB(ret.bounds.topBits), botZeroes};
|
ret.bounds.topBits = {truncateLSB(ret.bounds.topBits), botZeroes};
|
||||||
end
|
end
|
||||||
|
|
||||||
// Return derived capability
|
// Return derived capability
|
||||||
return tuple2(ret, resultExact);
|
return tuple2(ret, resultExact);
|
||||||
endfunction
|
endfunction
|
||||||
@@ -511,7 +511,7 @@ function CapFat unseal(CapFat cap, x _);
|
|||||||
ret.otype = otype_unsealed;
|
ret.otype = otype_unsealed;
|
||||||
return ret;
|
return ret;
|
||||||
endfunction
|
endfunction
|
||||||
function VnD#(CapFat) incOffset(CapFat cap, LCapAddress pointer, Bit#(CapAddressW) offset/*this is the increment in inc offset, and the offset in set offset*/, TempFields tf, Bool setOffset);
|
function VnD#(CapFat) incOffsetFat(CapFat cap, LCapAddress pointer, Bit#(CapAddressW) offset/*this is the increment in inc offset, and the offset in set offset*/, TempFields tf, Bool setOffset);
|
||||||
// NOTE:
|
// NOTE:
|
||||||
// The 'offset' argument is the "increment" value when setOffset is false,
|
// The 'offset' argument is the "increment" value when setOffset is false,
|
||||||
// and the actual "offset" value when setOffset is true.
|
// and the actual "offset" value when setOffset is true.
|
||||||
@@ -766,7 +766,7 @@ function Tuple2#(Format, Bounds) decBounds (CBounds raw);
|
|||||||
//bounds.topBits = 0;
|
//bounds.topBits = 0;
|
||||||
//bounds.baseBits = 0;
|
//bounds.baseBits = 0;
|
||||||
Bit#(HalfExpW) halfExp0 = 0;
|
Bit#(HalfExpW) halfExp0 = 0;
|
||||||
|
|
||||||
case (format)
|
case (format)
|
||||||
EmbeddedExp: begin
|
EmbeddedExp: begin
|
||||||
BoundsEmbeddedExp b = unpack(raw);
|
BoundsEmbeddedExp b = unpack(raw);
|
||||||
@@ -870,7 +870,6 @@ instance CHERICap #(CapMem, OTypeW, FlagsW, CapAddressW, CapW, TSub#(MW, 3));
|
|||||||
function setType = error("feature not implemented for this cap type");
|
function setType = error("feature not implemented for this cap type");
|
||||||
function getAddr = error("feature not implemented for this cap type");
|
function getAddr = error("feature not implemented for this cap type");
|
||||||
function setAddr = error("feature not implemented for this cap type");
|
function setAddr = error("feature not implemented for this cap type");
|
||||||
function maskAddr = error("feature not implemented for this cap type");
|
|
||||||
function getOffset = error("feature not implemented for this cap type");
|
function getOffset = error("feature not implemented for this cap type");
|
||||||
function modifyOffset = error("feature not implemented for this cap type");
|
function modifyOffset = error("feature not implemented for this cap type");
|
||||||
function getBase = error("feature not implemented for this cap type");
|
function getBase = error("feature not implemented for this cap type");
|
||||||
@@ -884,72 +883,44 @@ instance CHERICap #(CapMem, OTypeW, FlagsW, CapAddressW, CapW, TSub#(MW, 3));
|
|||||||
function validAsType = error("feature not implemented for this cap type");
|
function validAsType = error("feature not implemented for this cap type");
|
||||||
function fromMem = error("feature not implemented for this cap type");
|
function fromMem = error("feature not implemented for this cap type");
|
||||||
function toMem = error("feature not implemented for this cap type");
|
function toMem = error("feature not implemented for this cap type");
|
||||||
|
function maskAddr = error("feature not implemented for this cap type");
|
||||||
|
function getBaseAlignment = error("feature not implemented for this cap type");
|
||||||
endinstance
|
endinstance
|
||||||
|
|
||||||
instance CHERICap #(CapReg, OTypeW, FlagsW, CapAddressW, CapW, TSub#(MW, 3));
|
instance CHERICap #(CapReg, OTypeW, FlagsW, CapAddressW, CapW, TSub#(MW, 3));
|
||||||
function isValidCap = error("feature not implemented for this cap type");
|
|
||||||
function setValidCap = error("feature not implemented for this cap type");
|
|
||||||
function getFlags = error("feature not implemented for this cap type");
|
|
||||||
function setFlags = error("feature not implemented for this cap type");
|
|
||||||
function getHardPerms = error("feature not implemented for this cap type");
|
|
||||||
function setHardPerms = error("feature not implemented for this cap type");
|
|
||||||
function getSoftPerms = error("feature not implemented for this cap type");
|
|
||||||
function setSoftPerms = error("feature not implemented for this cap type");
|
|
||||||
function getKind = error("feature not implemented for this cap type");
|
|
||||||
function getType = error("feature not implemented for this cap type");
|
|
||||||
function setType = error("feature not implemented for this cap type");
|
|
||||||
function getAddr = error("feature not implemented for this cap type");
|
|
||||||
function setAddr = error("feature not implemented for this cap type");
|
|
||||||
function maskAddr = error("feature not implemented for this cap type");
|
|
||||||
function getOffset = error("feature not implemented for this cap type");
|
|
||||||
function modifyOffset = error("feature not implemented for this cap type");
|
|
||||||
function getBase = error("feature not implemented for this cap type");
|
|
||||||
function getTop = error("feature not implemented for this cap type");
|
|
||||||
function getLength = error("feature not implemented for this cap type");
|
|
||||||
function isInBounds = error("feature not implemented for this cap type");
|
|
||||||
function setBounds = error("feature not implemented for this cap type");
|
|
||||||
function nullWithAddr = error("feature not implemented for this cap type");
|
|
||||||
function almightyCap = defaultCapFat;
|
|
||||||
function nullCap = null_cap;
|
|
||||||
function validAsType = error("feature not implemented for this cap type");
|
|
||||||
function fromMem = error("feature not implemented for this cap type");
|
|
||||||
function toMem = error("feature not implemented for this cap type");
|
|
||||||
endinstance
|
|
||||||
|
|
||||||
instance CHERICap #(CapPipe, OTypeW, FlagsW, CapAddressW, CapW, TSub#(MW, 3));
|
function isValidCap (x) = x.isCapability;
|
||||||
|
|
||||||
function isValidCap (x) = x.capFat.isCapability;
|
function CapReg setValidCap (CapReg cap, Bool tag);
|
||||||
|
cap.isCapability = tag;
|
||||||
function CapPipe setValidCap (CapPipe cap, Bool tag);
|
|
||||||
cap.capFat.isCapability = tag;
|
|
||||||
return cap;
|
return cap;
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function getFlags (cap) = cap.capFat.flags;
|
function getFlags (cap) = cap.flags;
|
||||||
function setFlags (cap, flags);
|
function setFlags (cap, flags);
|
||||||
cap.capFat.flags = flags;
|
cap.flags = flags;
|
||||||
return cap;
|
return cap;
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function HardPerms getHardPerms (CapPipe cap);
|
function HardPerms getHardPerms (CapReg cap);
|
||||||
return HardPerms {
|
return HardPerms {
|
||||||
permitSetCID: cap.capFat.perms.hard.permit_set_CID,
|
permitSetCID: cap.perms.hard.permit_set_CID,
|
||||||
accessSysRegs: cap.capFat.perms.hard.access_sys_regs,
|
accessSysRegs: cap.perms.hard.access_sys_regs,
|
||||||
permitUnseal: cap.capFat.perms.hard.permit_unseal,
|
permitUnseal: cap.perms.hard.permit_unseal,
|
||||||
permitCCall: cap.capFat.perms.hard.permit_ccall,
|
permitCCall: cap.perms.hard.permit_ccall,
|
||||||
permitSeal: cap.capFat.perms.hard.permit_seal,
|
permitSeal: cap.perms.hard.permit_seal,
|
||||||
permitStoreLocalCap: cap.capFat.perms.hard.permit_store_ephemeral_cap,
|
permitStoreLocalCap: cap.perms.hard.permit_store_ephemeral_cap,
|
||||||
permitStoreCap: cap.capFat.perms.hard.permit_store_cap,
|
permitStoreCap: cap.perms.hard.permit_store_cap,
|
||||||
permitLoadCap: cap.capFat.perms.hard.permit_load_cap,
|
permitLoadCap: cap.perms.hard.permit_load_cap,
|
||||||
permitStore: cap.capFat.perms.hard.permit_store,
|
permitStore: cap.perms.hard.permit_store,
|
||||||
permitLoad: cap.capFat.perms.hard.permit_load,
|
permitLoad: cap.perms.hard.permit_load,
|
||||||
permitExecute: cap.capFat.perms.hard.permit_execute,
|
permitExecute: cap.perms.hard.permit_execute,
|
||||||
global: cap.capFat.perms.hard.non_ephemeral
|
global: cap.perms.hard.non_ephemeral
|
||||||
};
|
};
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function CapPipe setHardPerms (CapPipe cap, HardPerms perms);
|
function CapReg setHardPerms (CapReg cap, HardPerms perms);
|
||||||
cap.capFat.perms.hard = HPerms {
|
cap.perms.hard = HPerms {
|
||||||
permit_set_CID: perms.permitSetCID,
|
permit_set_CID: perms.permitSetCID,
|
||||||
access_sys_regs: perms.accessSysRegs,
|
access_sys_regs: perms.accessSysRegs,
|
||||||
permit_unseal: perms.permitUnseal,
|
permit_unseal: perms.permitUnseal,
|
||||||
@@ -966,38 +937,148 @@ instance CHERICap #(CapPipe, OTypeW, FlagsW, CapAddressW, CapW, TSub#(MW, 3));
|
|||||||
return cap;
|
return cap;
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function SoftPerms getSoftPerms (CapPipe cap);
|
function SoftPerms getSoftPerms (CapReg cap);
|
||||||
return zeroExtend(cap.capFat.perms.soft);
|
return zeroExtend(cap.perms.soft);
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function CapPipe setSoftPerms (CapPipe cap, SoftPerms perms);
|
function CapReg setSoftPerms (CapReg cap, SoftPerms perms);
|
||||||
cap.capFat.perms.soft = truncate(perms);
|
cap.perms.soft = truncate(perms);
|
||||||
return cap;
|
return cap;
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function Kind getKind (CapPipe cap);
|
function Kind getKind (CapReg cap);
|
||||||
case (cap.capFat.otype)
|
case (cap.otype)
|
||||||
otype_unsealed: return UNSEALED;
|
otype_unsealed: return UNSEALED;
|
||||||
otype_sentry: return SENTRY;
|
otype_sentry: return SENTRY;
|
||||||
default: return (cap.capFat.otype <= otype_max) ? SEALED_WITH_TYPE : RES0;
|
default: return (cap.otype <= otype_max) ? SEALED_WITH_TYPE : RES0;
|
||||||
endcase
|
endcase
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function getType (x) = getType(x.capFat).d;
|
function getType (cap) = getTypeFat(cap).d;
|
||||||
|
|
||||||
function Exact#(CapPipe) setType (CapPipe cap, Bit #(OTypeW) otype);
|
function CapReg setType (CapReg cap, Bit #(OTypeW) otype);
|
||||||
if (otype == -1) begin
|
if (otype == -1) begin
|
||||||
cap.capFat = unseal(cap.capFat, ?);
|
cap = unseal(cap, ?);
|
||||||
end else begin
|
end else begin
|
||||||
cap.capFat = seal(cap.capFat, ?, VnD {v: True, d:otype});
|
cap = seal(cap, ?, VnD {v: True, d:otype});
|
||||||
end
|
end
|
||||||
return Exact {
|
return cap;
|
||||||
exact: True,
|
|
||||||
value: cap
|
|
||||||
};
|
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function getAddr (x) = truncate(getAddress(x.capFat));
|
function getAddr (cap) = truncate(getAddress(cap));
|
||||||
|
|
||||||
|
function setAddr = error("feature not implemented for this cap type");
|
||||||
|
|
||||||
|
function getOffset = error("feature not implemented for this cap type");
|
||||||
|
function modifyOffset = error("feature not implemented for this cap type");
|
||||||
|
function getBase = error("feature not implemented for this cap type");
|
||||||
|
function getTop = error("feature not implemented for this cap type");
|
||||||
|
function getLength = error("feature not implemented for this cap type");
|
||||||
|
function isInBounds = error("feature not implemented for this cap type");
|
||||||
|
|
||||||
|
function Exact#(CapReg) setBounds (CapReg cap, Bit#(CapAddressW) length);
|
||||||
|
match {.result, .exact} = setBoundsFat(cap, length);
|
||||||
|
return Exact {exact: exact, value: result};
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function CapReg nullWithAddr (Bit#(CapAddressW) addr);
|
||||||
|
CapReg res = nullCap;
|
||||||
|
res.address = zeroExtend(addr);
|
||||||
|
return res;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function almightyCap = defaultCapFat;
|
||||||
|
|
||||||
|
function nullCap = null_cap;
|
||||||
|
|
||||||
|
function Bool validAsType (CapReg dummy, Bit#(CapAddressW) checkType);
|
||||||
|
UInt#(CapAddressW) checkTypeUnsigned = unpack(checkType);
|
||||||
|
UInt#(CapAddressW) otypeMaxUnsigned = unpack(zeroExtend(otype_max));
|
||||||
|
return checkTypeUnsigned <= otypeMaxUnsigned;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function fromMem (x) = cast(pack(x));
|
||||||
|
|
||||||
|
function toMem (x) = unpack(cast(x));
|
||||||
|
|
||||||
|
function CapReg maskAddr (CapReg cap, Bit#(TSub#(MW, 3)) mask);
|
||||||
|
cap.address[valueOf(TSub#(MW, 4)):0] = cap.address[valueOf(TSub#(MW, 4)):0] & mask;
|
||||||
|
return cap;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function Bit#(2) getBaseAlignment (CapReg cap);
|
||||||
|
// If cap exp is non-zero, we have internal exponent, so the least significant
|
||||||
|
// two bits of the base are implicitly zero.
|
||||||
|
// Otherwise, we have a zero exponent, so the least significant two bits
|
||||||
|
// of the base are the least significant bits of the encoded base
|
||||||
|
if (cap.bounds.exp == 0) return cap.bounds.baseBits[1:0];
|
||||||
|
else return 2'b0;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
endinstance
|
||||||
|
|
||||||
|
instance CHERICap #(CapPipe, OTypeW, FlagsW, CapAddressW, CapW, TSub#(MW, 3));
|
||||||
|
|
||||||
|
//Functions supported by CapReg are just passed through
|
||||||
|
function isValidCap (x) = isValidCap(x.capFat);
|
||||||
|
function setValidCap (cap, tag);
|
||||||
|
return CapPipe {capFat: setValidCap(cap.capFat, tag), tempFields: cap.tempFields};
|
||||||
|
endfunction
|
||||||
|
function getFlags (cap) = getFlags(cap.capFat);
|
||||||
|
function setFlags (cap, flags);
|
||||||
|
return CapPipe {capFat: setFlags(cap.capFat, flags), tempFields: cap.tempFields};
|
||||||
|
endfunction
|
||||||
|
function getHardPerms (cap) = getHardPerms(cap.capFat);
|
||||||
|
function CapPipe setHardPerms (CapPipe cap, HardPerms perms);
|
||||||
|
return CapPipe {capFat: setHardPerms(cap.capFat, perms), tempFields: cap.tempFields};
|
||||||
|
endfunction
|
||||||
|
function getSoftPerms (cap) = getSoftPerms(cap.capFat);
|
||||||
|
function CapPipe setSoftPerms (CapPipe cap, SoftPerms perms);
|
||||||
|
return CapPipe {capFat: setSoftPerms(cap.capFat, perms), tempFields: cap.tempFields};
|
||||||
|
endfunction
|
||||||
|
function getKind (cap) = getKind(cap.capFat);
|
||||||
|
function getType (cap) = getType(cap.capFat);
|
||||||
|
function setType (cap, otype);
|
||||||
|
return CapPipe{capFat: setType(cap.capFat, otype), tempFields: cap.tempFields};
|
||||||
|
endfunction
|
||||||
|
function getAddr (cap) = getAddr(cap.capFat);
|
||||||
|
function CapPipe maskAddr (CapPipe cap, Bit#(TSub#(MW, 3)) mask);
|
||||||
|
return CapPipe {capFat: maskAddr(cap.capFat, mask), tempFields: cap.tempFields};
|
||||||
|
endfunction
|
||||||
|
function Bool validAsType (CapPipe dummy, Bit#(CapAddressW) checkType);
|
||||||
|
return validAsType(dummy.capFat, checkType);
|
||||||
|
endfunction
|
||||||
|
function toMem (cap) = toMem(cap.capFat);
|
||||||
|
function getBaseAlignment (cap) = getBaseAlignment(cap.capFat);
|
||||||
|
|
||||||
|
//Functions supported by CapReg but which require TempFields to be changed
|
||||||
|
|
||||||
|
function Exact#(CapPipe) setBounds (CapPipe cap, Bit#(CapAddressW) length);
|
||||||
|
let result = setBounds(cap.capFat, length);
|
||||||
|
return Exact {exact: result.exact, value: CapPipe {capFat: result.value, tempFields: getTempFields(result.value)}};
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function CapPipe nullWithAddr (Bit#(CapAddressW) addr);
|
||||||
|
CapReg res = nullWithAddr(addr);
|
||||||
|
return CapPipe {capFat: res, tempFields: getTempFields(res)};
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function fromMem (capBits);
|
||||||
|
CapReg res = fromMem(capBits);
|
||||||
|
return CapPipe {capFat: res, tempFields: getTempFields(res)};
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function almightyCap;
|
||||||
|
CapReg res = almightyCap;
|
||||||
|
return CapPipe {capFat: res, tempFields: getTempFields(res)};
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function nullCap;
|
||||||
|
CapReg res = nullCap;
|
||||||
|
return CapPipe {capFat: res, tempFields: getTempFields(res)};
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
//Functions that require TempFields
|
||||||
|
|
||||||
function Exact#(CapPipe) setAddr (CapPipe cap, Bit#(CapAddressW) address);
|
function Exact#(CapPipe) setAddr (CapPipe cap, Bit#(CapAddressW) address);
|
||||||
let result = setAddress(cap.capFat, zeroExtend(address), cap.tempFields);
|
let result = setAddress(cap.capFat, zeroExtend(address), cap.tempFields);
|
||||||
@@ -1006,15 +1087,10 @@ instance CHERICap #(CapPipe, OTypeW, FlagsW, CapAddressW, CapW, TSub#(MW, 3));
|
|||||||
return Exact {exact: result.v, value: cap};
|
return Exact {exact: result.v, value: cap};
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function CapPipe maskAddr (CapPipe cap, Bit#(TSub#(MW, 3)) mask);
|
|
||||||
cap.capFat.address[valueOf(TSub#(MW, 4)):0] = cap.capFat.address[valueOf(TSub#(MW, 4)):0] & mask;
|
|
||||||
return cap;
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function getOffset (x) = getOffsetFat(x.capFat, x.tempFields);
|
function getOffset (x) = getOffsetFat(x.capFat, x.tempFields);
|
||||||
|
|
||||||
function Exact#(CapPipe) modifyOffset (CapPipe cap, Bit#(CapAddressW) offset, Bool doInc);
|
function Exact#(CapPipe) modifyOffset (CapPipe cap, Bit#(CapAddressW) offset, Bool doInc);
|
||||||
let result = incOffset(cap.capFat, pack(cap.capFat.address) + zeroExtend(offset), zeroExtend(offset), cap.tempFields, !doInc);
|
let result = incOffsetFat(cap.capFat, pack(cap.capFat.address) + zeroExtend(offset), zeroExtend(offset), cap.tempFields, !doInc);
|
||||||
cap.capFat = result.d;
|
cap.capFat = result.d;
|
||||||
cap.tempFields = getTempFields(cap.capFat);
|
cap.tempFields = getTempFields(cap.capFat);
|
||||||
return Exact {exact: result.v, value: cap};
|
return Exact {exact: result.v, value: cap};
|
||||||
@@ -1036,30 +1112,6 @@ instance CHERICap #(CapPipe, OTypeW, FlagsW, CapAddressW, CapW, TSub#(MW, 3));
|
|||||||
return capInBounds(cap.capFat, cap.tempFields, inclusive);
|
return capInBounds(cap.capFat, cap.tempFields, inclusive);
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function Exact#(CapPipe) setBounds (CapPipe cap, Bit#(CapAddressW) length);
|
|
||||||
match {.result, .exact} = setBoundsFat(cap.capFat, length);
|
|
||||||
return Exact {exact: exact, value: CapPipe {capFat: result, tempFields: getTempFields(result)}};
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function CapPipe nullWithAddr (Bit#(CapAddressW) addr);
|
|
||||||
let res = setAddress(nullCap, zeroExtend(addr), getTempFields(nullCap)).d;
|
|
||||||
return CapPipe {capFat: res, tempFields: getTempFields(res)};
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function almightyCap = CapPipe { capFat: defaultCapFat, tempFields: getTempFields(defaultCapFat) };
|
|
||||||
|
|
||||||
function nullCap = CapPipe { capFat: nullCap, tempFields: getTempFields(nullCap) };
|
|
||||||
|
|
||||||
function Bool validAsType (CapPipe dummy, Bit#(CapAddressW) checkType);
|
|
||||||
UInt#(CapAddressW) checkTypeUnsigned = unpack(checkType);
|
|
||||||
UInt#(CapAddressW) otypeMaxUnsigned = unpack(zeroExtend(otype_max));
|
|
||||||
return checkTypeUnsigned <= otypeMaxUnsigned;
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function fromMem (x) = cast(pack(x));
|
|
||||||
|
|
||||||
function toMem (x) = unpack(cast(x));
|
|
||||||
|
|
||||||
endinstance
|
endinstance
|
||||||
|
|
||||||
instance Cast#(CapMem, CapReg);
|
instance Cast#(CapMem, CapReg);
|
||||||
@@ -1086,18 +1138,4 @@ instance Cast#(CapPipe, CapReg);
|
|||||||
endfunction
|
endfunction
|
||||||
endinstance
|
endinstance
|
||||||
|
|
||||||
instance Cast#(CapMem, CapPipe);
|
|
||||||
function cast(x);
|
|
||||||
CapReg fat = cast(x);
|
|
||||||
return cast(fat);
|
|
||||||
endfunction
|
|
||||||
endinstance
|
|
||||||
|
|
||||||
instance Cast#(CapPipe, CapMem);
|
|
||||||
function cast(x);
|
|
||||||
CapReg fat = cast(x);
|
|
||||||
return cast(fat);
|
|
||||||
endfunction
|
|
||||||
endinstance
|
|
||||||
|
|
||||||
endpackage
|
endpackage
|
||||||
|
|||||||
21
CHERICap.bsv
21
CHERICap.bsv
@@ -116,17 +116,12 @@ typeclass CHERICap#(type t, numeric type ot, numeric type flg, numeric type n, n
|
|||||||
// Get the type field, including implicitly whether the cap is sealed/sentry
|
// Get the type field, including implicitly whether the cap is sealed/sentry
|
||||||
function Bit#(ot) getType (t cap);
|
function Bit#(ot) getType (t cap);
|
||||||
// Set the type field, including implicitly sealing/unsealing the capability
|
// Set the type field, including implicitly sealing/unsealing the capability
|
||||||
// In the event the new type makes the cap unrepresentable
|
function t setType (t cap, Bit#(ot) otype);
|
||||||
function Exact#(t) setType (t cap, Bit#(ot) otype);
|
|
||||||
// Get the address pointed to by the capability
|
|
||||||
|
|
||||||
|
// Get the address pointed to by the capability
|
||||||
function Bit#(n) getAddr (t cap);
|
function Bit#(n) getAddr (t cap);
|
||||||
// Set the address of the capability. Result invalid if not exact
|
// Set the address of the capability. Result invalid if not exact
|
||||||
function Exact#(t) setAddr (t cap, Bit#(n) addr);
|
function Exact#(t) setAddr (t cap, Bit#(n) addr);
|
||||||
// Mask the least significant bits of capability address with a mask
|
|
||||||
// maskable_width should be small enough to make this
|
|
||||||
// safe with respect to representability
|
|
||||||
function t maskAddr (t cap, Bit#(maskable_bits) mask);
|
|
||||||
|
|
||||||
// Get the offset of the capability
|
// Get the offset of the capability
|
||||||
function Bit#(n) getOffset (t cap) = getAddr(cap) - getBase(cap);
|
function Bit#(n) getOffset (t cap) = getAddr(cap) - getBase(cap);
|
||||||
@@ -172,6 +167,18 @@ typeclass CHERICap#(type t, numeric type ot, numeric type flg, numeric type n, n
|
|||||||
function t fromMem (Tuple2#(Bool, Bit#(mem_sz)) mem_cap);
|
function t fromMem (Tuple2#(Bool, Bit#(mem_sz)) mem_cap);
|
||||||
function Tuple2#(Bool, Bit#(mem_sz)) toMem (t cap);
|
function Tuple2#(Bool, Bit#(mem_sz)) toMem (t cap);
|
||||||
|
|
||||||
|
// Functions that can be cheap by relying on current capability representation
|
||||||
|
|
||||||
|
// Mask the least significant bits of capability address with a mask
|
||||||
|
// maskable_width should be small enough to make this
|
||||||
|
// safe with respect to representability
|
||||||
|
function t maskAddr (t cap, Bit#(maskable_bits) mask);
|
||||||
|
|
||||||
|
// Check the alignment of the base, giving least significant 2 bits.
|
||||||
|
// This relies on the fact that internal exponents take up 2 bits of the
|
||||||
|
// base.
|
||||||
|
function Bit#(2) getBaseAlignment (t cap);
|
||||||
|
|
||||||
endtypeclass
|
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));
|
||||||
|
|||||||
Reference in New Issue
Block a user