Turn the address field in CapFat to a Bit#(CapAdressW) (with pdr32 and jdw57)
This commit is contained in:
105
CHERICC_Fat.bsv
105
CHERICC_Fat.bsv
@@ -45,7 +45,6 @@ export OTypeW;
|
||||
export FlagsW;
|
||||
export Perms;
|
||||
export ResW;
|
||||
export LCapAddress;
|
||||
export Format;
|
||||
export TempFields;
|
||||
export Bounds;
|
||||
@@ -92,7 +91,14 @@ typedef struct {
|
||||
typedef 64 CapAddressW;
|
||||
typedef 128 CapW;
|
||||
`endif
|
||||
typedef Bit#(CapAddressW) Address;
|
||||
// The Address type is used to represent the full sized address returned to the
|
||||
// consuming pipeline. In cases where fewer than CapAddressW bits are stored to
|
||||
// represent a memory address (and remaining bits are usable for storing extra
|
||||
// metadata), returning a value of type Address is currently expected to sign
|
||||
// extend the address.
|
||||
// SizeOf#(Address) should be greater or equal to CapAddressW
|
||||
typedef CapAddressW AddressW;
|
||||
typedef Bit#(AddressW) Address;
|
||||
typedef TDiv#(ExpW,2) HalfExpW;
|
||||
typedef TSub#(MW,HalfExpW) UpperMW;
|
||||
|
||||
@@ -138,7 +144,6 @@ typedef struct {
|
||||
typedef Bit#(TAdd#(CapW,1)) Capability;
|
||||
// not including the tag bit
|
||||
typedef Bit#(CapW) CapBits;
|
||||
typedef Bit#(128) ShortCap;
|
||||
/* TODO
|
||||
staticAssert(valueOf(SizeOf#(CapabilityInMemory))==valueOf(SizeOf#(Capability)),
|
||||
"The CapabilityInMemory type has incorrect size of " + integerToString(valueOf(SizeOf#(CapabilityInMemory))) + " (CapW = " + integerToString(valueOf(CapW)) + ")"
|
||||
@@ -162,15 +167,15 @@ Bit#(OTypeW) otype_res1 = -4;
|
||||
|
||||
// unpacked capability format
|
||||
typedef struct {
|
||||
Bool isCapability;
|
||||
LCapAddress address;
|
||||
Bit#(MW) addrBits;
|
||||
Perms perms;
|
||||
Bit#(FlagsW) flags;
|
||||
Bit#(ResW) reserved;
|
||||
Bit#(OTypeW) otype;
|
||||
Format format;
|
||||
Bounds bounds;
|
||||
Bool isCapability;
|
||||
Bit#(CapAddressW) address;
|
||||
Bit#(MW) addrBits;
|
||||
Perms perms;
|
||||
Bit#(FlagsW) flags;
|
||||
Bit#(ResW) reserved;
|
||||
Bit#(OTypeW) otype;
|
||||
Format format;
|
||||
Bounds bounds;
|
||||
} CapFat deriving(Bits);
|
||||
|
||||
// "Architectural FShow"
|
||||
@@ -221,7 +226,7 @@ function CapFat unpackCap(Capability thin);
|
||||
match {.f, .b} = decBounds(memCap.bounds);
|
||||
fat.format = f;
|
||||
fat.bounds = b;
|
||||
fat.address = zeroExtend(memCap.address);
|
||||
fat.address = memCap.address;
|
||||
// The next few lines are to optimise the critical path of generating addrBits.
|
||||
// The value of Exp can now be 0 or come from token, so assume they come from the token,
|
||||
// then select the lower bits at the end if they didn't after all.
|
||||
@@ -241,20 +246,11 @@ function Capability packCap(CapFat fat);
|
||||
reserved: fat.reserved,
|
||||
otype: fat.otype,
|
||||
bounds: encBounds(fat.format,fat.bounds),
|
||||
address: truncate(fat.address)
|
||||
address: fat.address
|
||||
};
|
||||
return pack(thin);
|
||||
endfunction
|
||||
|
||||
// XXX needs double checking
|
||||
function ShortCap getShortCap (CapFat cap);
|
||||
CapabilityInMemory ret = unpack(packCap(cap));
|
||||
// put tag bit in highest reserved bit
|
||||
if (valueOf(ResW)!=0) ret.reserved[valueOf(ResW)-1] = pack(cap.isCapability);
|
||||
CapBits retbits = truncate(pack(ret));
|
||||
return zeroExtend(retbits);
|
||||
endfunction
|
||||
|
||||
// The temporary fields
|
||||
typedef MetaInfo TempFields;
|
||||
|
||||
@@ -269,11 +265,10 @@ function LCapAddress getBotFat(CapFat cap, TempFields tf);
|
||||
CapAddress addBase = signExtend({pack(tf.baseCorrection), cap.bounds.baseBits}) << cap.bounds.exp;
|
||||
// Build a mask on the high bits of a full length value to extract the high
|
||||
// bits of the address.
|
||||
Bit#(TSub#(SizeOf#(CapAddress),MW)) mask = ~0 << cap.bounds.exp;
|
||||
Bit#(TSub#(CapAddressW,MW)) mask = ~0 << cap.bounds.exp;
|
||||
// Extract the high bits of the address (and append the implied zeros at the
|
||||
// bottom), and add with the previously prepared value.
|
||||
CapAddress adr = truncate(cap.address); // Trim top bits of address.
|
||||
CapAddress bot = {truncateLSB(adr)&mask,0} + addBase;
|
||||
CapAddress bot = {truncateLSB(cap.address)&mask,0} + addBase;
|
||||
return zeroExtend(bot);
|
||||
endfunction
|
||||
function LCapAddress getTopFat(CapFat cap, TempFields tf);
|
||||
@@ -285,7 +280,7 @@ function LCapAddress getTopFat(CapFat cap, TempFields tf);
|
||||
Bit#(TSub#(SizeOf#(LCapAddress),MW)) mask = ~0 << cap.bounds.exp;
|
||||
// Extract the high bits of the address (and append the implied zeros at the
|
||||
// bottom), and add with the previously prepared value.
|
||||
LCapAddress ret = {truncateLSB(cap.address)&mask,0} + addTop;
|
||||
LCapAddress ret = {2'b0, truncateLSB(cap.address)&mask,0} + addTop;
|
||||
// If the bottom and top are more than an address space away from eachother, invert
|
||||
// the 64th/32nd bit of Top. This corrects for errors that happen when the representable
|
||||
// space wraps the address space.
|
||||
@@ -293,9 +288,8 @@ function LCapAddress getTopFat(CapFat cap, TempFields tf);
|
||||
ret[msbp+2] = 0;
|
||||
Bit#(2) topTip = ret[msbp+1:msbp];
|
||||
// Calculate the msb of the base.
|
||||
CapAddress adr = truncate(cap.address);
|
||||
// First assume that only the address and correction are involved...
|
||||
Bit#(TSub#(SizeOf#(CapAddress),MW)) bot = truncateLSB(adr) + (signExtend(pack(tf.baseCorrection)) << cap.bounds.exp);
|
||||
Bit#(TSub#(CapAddressW,MW)) bot = truncateLSB(cap.address) + (signExtend(pack(tf.baseCorrection)) << cap.bounds.exp);
|
||||
Bit#(1) botTip = msb(bot);
|
||||
// If the bit we're interested in are actually coming from baseBits, select the correct one from there.
|
||||
// exp == (resetExp - 1) doesn't matter since we will not flip unless exp < resetExp-1.
|
||||
@@ -323,17 +317,12 @@ function Address getOffsetFat(CapFat cap, TempFields tf);
|
||||
Bit#(TAdd#(MW,2)) base = {pack(tf.baseCorrection),cap.bounds.baseBits};
|
||||
// Get the offset bits by substracting the previous value from the addrBits
|
||||
Bit#(TAdd#(MW,2)) offset = zeroExtend(cap.addrBits) - base;
|
||||
// Grab the bottom bits of the address
|
||||
Address addrLSB = lAddrToReg(cap.address & ~(~0 << e));
|
||||
// Grab the bottom bits of the address and sign extend them to the size of Address
|
||||
Address addrLSB = signExtend(cap.address & ~(~0 << e));
|
||||
// Return the computed offset bits (sign extended) shifted appropriatly,
|
||||
// with the low address bits appended
|
||||
return (signExtend(offset) << e) | addrLSB;
|
||||
endfunction
|
||||
function LCapAddress getAddress(CapFat cap) = cap.address;
|
||||
function Address lAddrToReg(LCapAddress in);
|
||||
CapAddress retVal = truncate(in);
|
||||
return signExtend(retVal);
|
||||
endfunction
|
||||
function LCapAddress regToLAddr(Address in);
|
||||
CapAddress retVal = truncate(in);
|
||||
return zeroExtend(retVal);
|
||||
@@ -364,35 +353,22 @@ function Bool capInBounds(CapFat cap, TempFields tf, Bool inclusive);
|
||||
endfunction
|
||||
function CapFat nullifyCap(CapFat cap);
|
||||
CapFat ret = nullCap;
|
||||
CapAddress tmpAddr = truncate(cap.address);
|
||||
ret.addrBits = {2'b0,truncateLSB(tmpAddr)};
|
||||
ret.addrBits = {2'b0,truncateLSB(cap.address)};
|
||||
ret.address = cap.address;
|
||||
//CapFat ret = cap;
|
||||
//ret.isCapability = False;
|
||||
return ret;
|
||||
endfunction
|
||||
function CapFat pccJumpUpdate(CapFat pcc, LCapAddress fullBot);
|
||||
// Set the appropriate fields in PCC when jumping.
|
||||
pcc.address = fullBot;
|
||||
pcc.addrBits = pcc.bounds.baseBits;
|
||||
return pcc;
|
||||
endfunction
|
||||
function CapFat setCapPointer(CapFat cap, LCapAddress pointer);
|
||||
// Function to "cheat" and just set the pointer when we know that
|
||||
// it will be in representable bounds by some other means.
|
||||
CapFat ret = cap;
|
||||
ret.address = pointer;
|
||||
ret.address = truncate(pointer);
|
||||
ret.addrBits = truncate(ret.address >> ret.bounds.exp);
|
||||
return ret;
|
||||
endfunction
|
||||
// Only currently used for algorithm comparison.
|
||||
|
||||
function Bool boundsCheck(CapFat cap, Bit#(CapAddressW) off, TempFields tf);
|
||||
Bit#(TAdd#(CapAddressW,2)) bo = zeroExtend(off);
|
||||
cap = incOffsetFat(cap, cap.address+truncate(bo), off, tf, False).d;
|
||||
return cap.isCapability && capInBounds(cap, tf, False);
|
||||
endfunction
|
||||
|
||||
function Bit#(n) smearMSBRight(Bit#(n) x);
|
||||
Bit#(n) res = x;
|
||||
for (Integer i = 0; i < valueOf(TLog#(n))-1; i = i + 1)
|
||||
@@ -400,7 +376,6 @@ function Bit#(n) smearMSBRight(Bit#(n) x);
|
||||
return res;
|
||||
endfunction
|
||||
|
||||
|
||||
function SetBoundsReturn#(CapFat, CapAddressW) setBoundsFat(CapFat cap, Address lengthFull);
|
||||
CapFat ret = cap;
|
||||
// Find new exponent by finding the index of the most significant bit of the
|
||||
@@ -422,8 +397,7 @@ function SetBoundsReturn#(CapFat, CapAddressW) setBoundsFat(CapFat cap, Address
|
||||
ret.otype = otype_unsealed;
|
||||
// Derive new base bits by extracting MW bits from the capability
|
||||
// address starting at the new exponent's position.
|
||||
CapAddress tmpAddr = truncate(cap.address);
|
||||
LCapAddress base = zeroExtend(tmpAddr);
|
||||
LCapAddress base = zeroExtend(cap.address);
|
||||
Bit#(TAdd#(MW,1)) newBaseBits = truncate(base>>e);
|
||||
|
||||
// Derive new top bits by extracting MW bits from the capability
|
||||
@@ -540,7 +514,11 @@ function CapFat unseal(CapFat cap, x _);
|
||||
ret.otype = otype_unsealed;
|
||||
return ret;
|
||||
endfunction
|
||||
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);
|
||||
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:
|
||||
// The 'offset' argument is the "increment" value when setOffset is false,
|
||||
// and the actual "offset" value when setOffset is true.
|
||||
@@ -645,15 +623,16 @@ function VnD#(CapFat) incOffsetFat(CapFat cap, LCapAddress pointer, Bit#(CapAddr
|
||||
// ------------------------------
|
||||
if (setOffset) begin
|
||||
// Get the base and add the offsetAddr. This could be slow, but seems to pass timing.
|
||||
ret.address = getBotFat(cap,tf) + zeroExtend(offsetAddr);
|
||||
ret.address = truncate(getBotFat(cap,tf) + zeroExtend(offsetAddr));
|
||||
// TODO write comments on this
|
||||
Bit#(TAdd#(MW,2)) newAddrBits = zeroExtend(cap.bounds.baseBits) + zeroExtend(offsetBits);
|
||||
ret.addrBits = (e == resetExp) ? {1'b0,truncate(newAddrBits)}:truncate(newAddrBits);
|
||||
ret.addrBits = (e == resetExp) ? {2'b0,truncate(newAddrBits)} :
|
||||
(e == resetExp-1) ? {1'b0,truncate(newAddrBits)} :
|
||||
truncate(newAddrBits);
|
||||
end else begin
|
||||
// In the incOffset case, the 'pointer' argument already contains the new address
|
||||
CapAddress tmpAddr = truncate(pointer);
|
||||
ret.address = zeroExtend(tmpAddr);
|
||||
ret.addrBits = truncate(tmpAddr >> e);
|
||||
ret.address = truncate(pointer);
|
||||
ret.addrBits = truncate(ret.address >> e);
|
||||
end
|
||||
// Nullify the capability if the representable bounds check has failed
|
||||
if (!inBounds) ret.isCapability = False;//nullifyCap(ret);
|
||||
@@ -1055,7 +1034,7 @@ instance CHERICap #(CapReg, OTypeW, FlagsW, CapAddressW, CapW, TSub#(MW, 3));
|
||||
endcase);
|
||||
endfunction
|
||||
|
||||
function getAddr (cap) = truncate(getAddress(cap));
|
||||
function getAddr (cap) = cap.address;
|
||||
|
||||
function setAddr = error("setAddr not implemented for CapReg");
|
||||
|
||||
@@ -1085,7 +1064,7 @@ instance CHERICap #(CapReg, OTypeW, FlagsW, CapAddressW, CapW, TSub#(MW, 3));
|
||||
function toMem (x) = unpack(cast(x));
|
||||
|
||||
function CapReg maskAddr (CapReg cap, Bit#(TSub#(MW, 3)) mask);
|
||||
return setCapPointer(cap, cap.address & {~0,mask});
|
||||
return setCapPointer(cap, zeroExtend(cap.address) & {~0,mask});
|
||||
endfunction
|
||||
|
||||
function Bool validAsType (CapReg dummy, Bit#(CapAddressW) checkType);
|
||||
@@ -1189,7 +1168,7 @@ instance CHERICap #(CapPipe, OTypeW, FlagsW, CapAddressW, CapW, TSub#(MW, 3));
|
||||
function getOffset (x) = getOffsetFat(x.capFat, x.tempFields);
|
||||
|
||||
function Exact#(CapPipe) modifyOffset (CapPipe cap, Bit#(CapAddressW) offset, Bool doInc);
|
||||
let result = incOffsetFat(cap.capFat, pack(cap.capFat.address) + zeroExtend(offset), zeroExtend(offset), cap.tempFields, !doInc);
|
||||
let result = incOffsetFat(cap.capFat, zeroExtend(cap.capFat.address) + zeroExtend(offset), zeroExtend(offset), cap.tempFields, !doInc);
|
||||
cap.capFat = result.d;
|
||||
cap.tempFields = getTempFields(cap.capFat);
|
||||
return Exact {exact: result.v, value: cap};
|
||||
|
||||
Reference in New Issue
Block a user