Compare commits
5 Commits
master
...
master-128
| Author | SHA1 | Date | |
|---|---|---|---|
| 9d7de214d7 | |||
| 6120b13246 | |||
| 3c6d203186 | |||
| 6263041aa1 | |||
| 8f4feb2f1b |
860
CHERICC.bsv
860
CHERICC.bsv
@@ -1,452 +1,452 @@
|
|||||||
// /*-
|
/*-
|
||||||
// * Copyright (c) 2017-2019 Alexandre Joannou
|
* Copyright (c) 2017-2019 Alexandre Joannou
|
||||||
// * All rights reserved.
|
* All rights reserved.
|
||||||
// *
|
*
|
||||||
// * This software was developed by SRI International and the University of
|
* This software was developed by SRI International and the University of
|
||||||
// * Cambridge Computer Laboratory (Department of Computer Science and
|
* Cambridge Computer Laboratory (Department of Computer Science and
|
||||||
// * Technology) under DARPA contract HR0011-18-C-0016 ("ECATS"), as part of the
|
* Technology) under DARPA contract HR0011-18-C-0016 ("ECATS"), as part of the
|
||||||
// * DARPA SSITH research programme.
|
* DARPA SSITH research programme.
|
||||||
// *
|
*
|
||||||
// * @BERI_LICENSE_HEADER_START@
|
* @BERI_LICENSE_HEADER_START@
|
||||||
// *
|
*
|
||||||
// * Licensed to BERI Open Systems C.I.C. (BERI) under one or more contributor
|
* Licensed to BERI Open Systems C.I.C. (BERI) under one or more contributor
|
||||||
// * license agreements. See the NOTICE file distributed with this work for
|
* license agreements. See the NOTICE file distributed with this work for
|
||||||
// * additional information regarding copyright ownership. BERI licenses this
|
* additional information regarding copyright ownership. BERI licenses this
|
||||||
// * file to you under the BERI Hardware-Software License, Version 1.0 (the
|
* file to you under the BERI Hardware-Software License, Version 1.0 (the
|
||||||
// * "License"); you may not use this file except in compliance with the
|
* "License"); you may not use this file except in compliance with the
|
||||||
// * License. You may obtain a copy of the License at:
|
* License. You may obtain a copy of the License at:
|
||||||
// *
|
*
|
||||||
// * http://www.beri-open-systems.org/legal/license-1-0.txt
|
* http://www.beri-open-systems.org/legal/license-1-0.txt
|
||||||
// *
|
*
|
||||||
// * Unless required by applicable law or agreed to in writing, Work distributed
|
* Unless required by applicable law or agreed to in writing, Work distributed
|
||||||
// * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
// * CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// * specific language governing permissions and limitations under the License.
|
* specific language governing permissions and limitations under the License.
|
||||||
// *
|
*
|
||||||
// * @BERI_LICENSE_HEADER_END@
|
* @BERI_LICENSE_HEADER_END@
|
||||||
// */
|
*/
|
||||||
|
|
||||||
// package CHERICC;
|
package CHERICC;
|
||||||
|
|
||||||
// import CHERICap :: *;
|
import CHERICap :: *;
|
||||||
|
|
||||||
// export CHERICCCap;
|
export CHERICCCap;
|
||||||
// export CHERICCBounds;
|
export CHERICCBounds;
|
||||||
|
|
||||||
// `define div2(x) TDiv#(x, 2)
|
`define div2(x) TDiv#(x, 2)
|
||||||
// `define sub2(x) TSub#(x, 2)
|
`define sub2(x) TSub#(x, 2)
|
||||||
// `define i(x) valueOf(x)
|
`define i(x) valueOf(x)
|
||||||
|
|
||||||
// // CHERICCBounds Bounds type
|
// CHERICCBounds Bounds type
|
||||||
// ////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// // CHERICC compressed bounds type
|
// CHERICC compressed bounds type
|
||||||
// typedef union tagged {
|
typedef union tagged {
|
||||||
// struct {
|
struct {
|
||||||
// Bit#(1) lenMSB;
|
Bit#(1) lenMSB;
|
||||||
// Bit#(`sub2(base_)) top;
|
Bit#(`sub2(base_)) top;
|
||||||
// Bit#(base_) base;
|
Bit#(base_) base;
|
||||||
// } Exp0;
|
} Exp0;
|
||||||
// struct {
|
struct {
|
||||||
// Bit#(TSub#(`sub2(base_), `div2(e_))) top;
|
Bit#(TSub#(`sub2(base_), `div2(e_))) top;
|
||||||
// Bit#(TSub#(base_, `div2(e_))) base;
|
Bit#(TSub#(base_, `div2(e_))) base;
|
||||||
// Bit#(e_) e;
|
Bit#(e_) e;
|
||||||
// } EmbeddedExp;
|
} EmbeddedExp;
|
||||||
// struct {
|
struct {
|
||||||
// Bit#(TSub#(`sub2(base_), TAdd#(`div2(t_), `div2(e_)))) top;
|
Bit#(TSub#(`sub2(base_), TAdd#(`div2(t_), `div2(e_)))) top;
|
||||||
// Bit#(TSub#(base_, TAdd#(`div2(t_), `div2(e_)))) base;
|
Bit#(TSub#(base_, TAdd#(`div2(t_), `div2(e_)))) base;
|
||||||
// Bit#(t_) otype;
|
Bit#(t_) otype;
|
||||||
// Bit#(e_) e;
|
Bit#(e_) e;
|
||||||
// } Sealed;
|
} Sealed;
|
||||||
// } CHERICCBounds#(numeric type base_, numeric type e_, numeric type t_);
|
} CHERICCBounds#(numeric type base_, numeric type e_, numeric type t_);
|
||||||
|
|
||||||
// instance Bits#(CHERICCBounds#(b_, e_, t_), TMul#(b_, 2)) provisos(
|
instance Bits#(CHERICCBounds#(b_, e_, t_), TMul#(b_, 2)) provisos(
|
||||||
// // in pack
|
// in pack
|
||||||
// Add#(TDiv#(e_, 2), a__, e_), // truncates on e
|
Add#(TDiv#(e_, 2), a__, e_), // truncates on e
|
||||||
// Add#(TDiv#(t_, 2), b__, t_), // truncates on t
|
Add#(TDiv#(t_, 2), b__, t_), // truncates on t
|
||||||
// Add#(2, c__, b_), // 2 bits stolen from top
|
Add#(2, c__, b_), // 2 bits stolen from top
|
||||||
// // in unpack
|
// in unpack
|
||||||
// Add#(d__, TDiv#(e_, 2), TMul#(b_, 2)), // truncates raw into e
|
Add#(d__, TDiv#(e_, 2), TMul#(b_, 2)), // truncates raw into e
|
||||||
// Add#(e__, TDiv#(t_, 2), TMul#(b_, 2)), // truncates raw into t
|
Add#(e__, TDiv#(t_, 2), TMul#(b_, 2)), // truncates raw into t
|
||||||
// Add#(2, f__, TSub#(
|
Add#(2, f__, TSub#(
|
||||||
// TSub#(
|
TSub#(
|
||||||
// TAdd#(b_,
|
TAdd#(b_,
|
||||||
// TAdd#(
|
TAdd#(
|
||||||
// TDiv#(t_, 2),
|
TDiv#(t_, 2),
|
||||||
// TDiv#(e_, 2))),
|
TDiv#(e_, 2))),
|
||||||
// TDiv#(e_, 2)),
|
TDiv#(e_, 2)),
|
||||||
// TDiv#(t_, 2)))
|
TDiv#(t_, 2)))
|
||||||
// );
|
);
|
||||||
// function pack(ccbounds) =
|
function pack(ccbounds) =
|
||||||
// case (ccbounds) matches
|
case (ccbounds) matches
|
||||||
// tagged Exp0 .x: return {{{1'b0, x.lenMSB}, x.top}, x.base};
|
tagged Exp0 .x: return {{{1'b0, x.lenMSB}, x.top}, x.base};
|
||||||
// tagged EmbeddedExp .x: begin
|
tagged EmbeddedExp .x: begin
|
||||||
// Bit#(`div2(e_)) eHi = truncateLSB(x.e);
|
Bit#(`div2(e_)) eHi = truncateLSB(x.e);
|
||||||
// Bit#(`div2(e_)) eLo = truncate(x.e);
|
Bit#(`div2(e_)) eLo = truncate(x.e);
|
||||||
// return {{2'b10, x.top, eHi}, {x.base, eLo}};
|
return {{2'b10, x.top, eHi}, {x.base, eLo}};
|
||||||
// end
|
end
|
||||||
// tagged Sealed .x: begin
|
tagged Sealed .x: begin
|
||||||
// Bit#(`div2(t_)) tHi = truncateLSB(x.otype);
|
Bit#(`div2(t_)) tHi = truncateLSB(x.otype);
|
||||||
// Bit#(`div2(t_)) tLo = truncate(x.otype);
|
Bit#(`div2(t_)) tLo = truncate(x.otype);
|
||||||
// Bit#(`div2(e_)) eHi = truncateLSB(x.e);
|
Bit#(`div2(e_)) eHi = truncateLSB(x.e);
|
||||||
// Bit#(`div2(e_)) eLo = truncate(x.e);
|
Bit#(`div2(e_)) eLo = truncate(x.e);
|
||||||
// return {{2'b11, x.top, tHi, eHi}, {x.base, tLo, eLo}};
|
return {{2'b11, x.top, tHi, eHi}, {x.base, tLo, eLo}};
|
||||||
// /*
|
/*
|
||||||
// Bit#(TMul#(b_, 2)) acc = 0;
|
Bit#(TMul#(b_, 2)) acc = 0;
|
||||||
// acc = acc | zeroExtend(2'b11);
|
acc = acc | zeroExtend(2'b11);
|
||||||
// acc = (acc << `i(b_)-2-`i(t_)/2-`i(e_)/2) | zeroExtend(x.top);
|
acc = (acc << `i(b_)-2-`i(t_)/2-`i(e_)/2) | zeroExtend(x.top);
|
||||||
// acc = (acc << `i(t_)/2) | zeroExtend(tHi);
|
acc = (acc << `i(t_)/2) | zeroExtend(tHi);
|
||||||
// acc = (acc << `i(e_)/2) | zeroExtend(eHi);
|
acc = (acc << `i(e_)/2) | zeroExtend(eHi);
|
||||||
// acc = (acc << `i(b_)-`i(t_)/2-`i(e_)/2) | zeroExtend(x.base);
|
acc = (acc << `i(b_)-`i(t_)/2-`i(e_)/2) | zeroExtend(x.base);
|
||||||
// acc = (acc << `i(t_)/2) | zeroExtend(tLo);
|
acc = (acc << `i(t_)/2) | zeroExtend(tLo);
|
||||||
// acc = (acc << `i(e_)/2) | zeroExtend(eLo);
|
acc = (acc << `i(e_)/2) | zeroExtend(eLo);
|
||||||
// return acc;
|
return acc;
|
||||||
// */
|
*/
|
||||||
// end
|
end
|
||||||
// endcase;
|
endcase;
|
||||||
// function unpack(raw);
|
function unpack(raw);
|
||||||
// if (raw[2*`i(b_)-1] == 0) return Exp0 {
|
if (raw[2*`i(b_)-1] == 0) return Exp0 {
|
||||||
// lenMSB: raw[2*`i(b_)-2],
|
lenMSB: raw[2*`i(b_)-2],
|
||||||
// top: raw[2*`i(b_)-3:`i(b_)],
|
top: raw[2*`i(b_)-3:`i(b_)],
|
||||||
// base: raw[`i(b_)-1:0]
|
base: raw[`i(b_)-1:0]
|
||||||
// };
|
};
|
||||||
// else if (raw[2*`i(b_)-2] == 0) begin
|
else if (raw[2*`i(b_)-2] == 0) begin
|
||||||
// Bit#(`div2(e_)) eHi = truncate(raw >> `i(b_));
|
Bit#(`div2(e_)) eHi = truncate(raw >> `i(b_));
|
||||||
// Bit#(`div2(e_)) eLo = truncate(raw);
|
Bit#(`div2(e_)) eLo = truncate(raw);
|
||||||
// // XXX Bit#(e_) new_e = {eHi, eLo}; XXX simpler provisos with equiv line below
|
// XXX Bit#(e_) new_e = {eHi, eLo}; XXX simpler provisos with equiv line below
|
||||||
// Bit#(e_) new_e = zeroExtend(eLo) | zeroExtend(eHi) << `i(e_)/2;
|
Bit#(e_) new_e = zeroExtend(eLo) | zeroExtend(eHi) << `i(e_)/2;
|
||||||
// return EmbeddedExp {
|
return EmbeddedExp {
|
||||||
// top: raw[2*`i(b_)-3:`i(b_)+`i(e_)/2],
|
top: raw[2*`i(b_)-3:`i(b_)+`i(e_)/2],
|
||||||
// base: raw[`i(b_)-1:`i(e_)/2],
|
base: raw[`i(b_)-1:`i(e_)/2],
|
||||||
// e: new_e
|
e: new_e
|
||||||
// };
|
};
|
||||||
// end else begin
|
end else begin
|
||||||
// Bit#(`div2(t_)) tHi = truncate(raw >> (`i(b_)+(`i(e_)/2)));
|
Bit#(`div2(t_)) tHi = truncate(raw >> (`i(b_)+(`i(e_)/2)));
|
||||||
// Bit#(`div2(t_)) tLo = truncate(raw >> (`i(e_)/2));
|
Bit#(`div2(t_)) tLo = truncate(raw >> (`i(e_)/2));
|
||||||
// // XXX Bit#(t_) new_t = {tHi, tLo}; XXX simpler provisos with equiv line below
|
// XXX Bit#(t_) new_t = {tHi, tLo}; XXX simpler provisos with equiv line below
|
||||||
// Bit#(t_) new_t = zeroExtend(tLo) | zeroExtend(tHi) << `i(t_)/2;
|
Bit#(t_) new_t = zeroExtend(tLo) | zeroExtend(tHi) << `i(t_)/2;
|
||||||
// Bit#(`div2(e_)) eHi = truncate(raw >> `i(b_));
|
Bit#(`div2(e_)) eHi = truncate(raw >> `i(b_));
|
||||||
// Bit#(`div2(e_)) eLo = truncate(raw);
|
Bit#(`div2(e_)) eLo = truncate(raw);
|
||||||
// // XXX Bit#(e_) new_e = {eHi, eLo}; XXX simpler provisos with equiv line below
|
// XXX Bit#(e_) new_e = {eHi, eLo}; XXX simpler provisos with equiv line below
|
||||||
// Bit#(e_) new_e = zeroExtend(eLo) | zeroExtend(eHi) << `i(e_)/2;
|
Bit#(e_) new_e = zeroExtend(eLo) | zeroExtend(eHi) << `i(e_)/2;
|
||||||
// return Sealed {
|
return Sealed {
|
||||||
// top: raw[2*`i(b_)-3:`i(b_)+`i(e_)/2+`i(t_)/2],
|
top: raw[2*`i(b_)-3:`i(b_)+`i(e_)/2+`i(t_)/2],
|
||||||
// base: raw[`i(b_)-1:`i(e_)/2+`i(t_)/2],
|
base: raw[`i(b_)-1:`i(e_)/2+`i(t_)/2],
|
||||||
// otype: new_t,
|
otype: new_t,
|
||||||
// e: new_e
|
e: new_e
|
||||||
// };
|
};
|
||||||
// end
|
end
|
||||||
// endfunction
|
endfunction
|
||||||
// endinstance
|
endinstance
|
||||||
|
|
||||||
// // CHERICC capability type
|
// CHERICC capability type
|
||||||
// ////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// `define CCSoftPerms Bit#(4)
|
`define CCSoftPerms Bit#(4)
|
||||||
// `define AllPermsSz TAdd#(SizeOf#(`CCSoftPerms), SizeOf#(HardPerms))
|
`define AllPermsSz TAdd#(SizeOf#(`CCSoftPerms), SizeOf#(HardPerms))
|
||||||
|
|
||||||
// typedef struct {
|
typedef struct {
|
||||||
// Bool isCap;
|
Bool isCap;
|
||||||
// `CCSoftPerms softperms;
|
`CCSoftPerms softperms;
|
||||||
// HardPerms hardperms;
|
HardPerms hardperms;
|
||||||
// Bit#(TSub#(addr_, TAdd#(bounds_, `AllPermsSz))) res; // 15 permission bits and bounds_ bits to deduct
|
Bit#(TSub#(addr_, TAdd#(bounds_, `AllPermsSz))) res; // 15 permission bits and bounds_ bits to deduct
|
||||||
// CHERICCBounds#(`div2(bounds_), e_, t_) bounds;
|
CHERICCBounds#(`div2(bounds_), e_, t_) bounds;
|
||||||
// Bit#(addr_) addr;
|
Bit#(addr_) addr;
|
||||||
// } CHERICCCap#(numeric type addr_, numeric type bounds_, numeric type e_, numeric type t_);
|
} CHERICCCap#(numeric type addr_, numeric type bounds_, numeric type e_, numeric type t_);
|
||||||
|
|
||||||
// instance Bits#(CHERICCCap#(addr_, bounds_, e_, t_),
|
instance Bits#(CHERICCCap#(addr_, bounds_, e_, t_),
|
||||||
// TAdd#(1, TAdd#(addr_, TAdd#(bounds_, TAdd#(res_, `AllPermsSz))))) provisos(
|
TAdd#(1, TAdd#(addr_, TAdd#(bounds_, TAdd#(res_, `AllPermsSz))))) provisos(
|
||||||
// Bits#(CHERICCBounds#(TDiv#(bounds_, 2), e_, t_), bounds_),
|
Bits#(CHERICCBounds#(TDiv#(bounds_, 2), e_, t_), bounds_),
|
||||||
// Add#(TAdd#(bounds_, `AllPermsSz), res_, addr_)
|
Add#(TAdd#(bounds_, `AllPermsSz), res_, addr_)
|
||||||
// );
|
);
|
||||||
// function pack(cap);
|
function pack(cap);
|
||||||
// Bit#(1) isCap = pack(cap.isCap);
|
Bit#(1) isCap = pack(cap.isCap);
|
||||||
// Bit#(SizeOf#(`CCSoftPerms)) softperms = cap.softperms;
|
Bit#(SizeOf#(`CCSoftPerms)) softperms = cap.softperms;
|
||||||
// Bit#(SizeOf#(HardPerms)) hardperms = pack(cap.hardperms);
|
Bit#(SizeOf#(HardPerms)) hardperms = pack(cap.hardperms);
|
||||||
// Bit#(res_) res = cap.res;
|
Bit#(res_) res = cap.res;
|
||||||
// Bit#(bounds_) bounds = pack(cap.bounds);
|
Bit#(bounds_) bounds = pack(cap.bounds);
|
||||||
// Bit#(addr_) addr = cap.addr;
|
Bit#(addr_) addr = cap.addr;
|
||||||
// return {isCap, softperms, hardperms, res, bounds, addr};
|
return {isCap, softperms, hardperms, res, bounds, addr};
|
||||||
// endfunction
|
endfunction
|
||||||
// //function pack(cap) = {cap.softperms, pack(cap.perms), cap.res, pack(cap.bounds), cap.addr};
|
//function pack(cap) = {cap.softperms, pack(cap.perms), cap.res, pack(cap.bounds), cap.addr};
|
||||||
// function unpack(raw) = CHERICCCap {
|
function unpack(raw) = CHERICCCap {
|
||||||
// isCap: unpack(msb(raw)),
|
isCap: unpack(msb(raw)),
|
||||||
// softperms: raw[2*`i(addr_)-1:2*`i(addr_)-`i(SizeOf#(`CCSoftPerms))],
|
softperms: raw[2*`i(addr_)-1:2*`i(addr_)-`i(SizeOf#(`CCSoftPerms))],
|
||||||
// hardperms: unpack(raw[2*`i(addr_)-5:2*`i(addr_)-`i(`AllPermsSz)]),
|
hardperms: unpack(raw[2*`i(addr_)-5:2*`i(addr_)-`i(`AllPermsSz)]),
|
||||||
// res: raw[2*`i(addr_)-`i(`AllPermsSz)-1:`i(addr_)+`i(bounds_)],
|
res: raw[2*`i(addr_)-`i(`AllPermsSz)-1:`i(addr_)+`i(bounds_)],
|
||||||
// bounds: unpack(raw[`i(addr_)+`i(bounds_)-1:`i(addr_)]),
|
bounds: unpack(raw[`i(addr_)+`i(bounds_)-1:`i(addr_)]),
|
||||||
// addr: raw[`i(addr_)-1:0]
|
addr: raw[`i(addr_)-1:0]
|
||||||
// };
|
};
|
||||||
// endinstance
|
endinstance
|
||||||
|
|
||||||
// `undef AllPermsSz
|
`undef AllPermsSz
|
||||||
// `undef CCSoftPerms
|
`undef CCSoftPerms
|
||||||
|
|
||||||
// // CHERICCCap inner helpers
|
// CHERICCCap inner helpers
|
||||||
// ////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// CHERICCCap#(addr_, bounds_, e_, t_) almightyCC = CHERICCCap {
|
CHERICCCap#(addr_, bounds_, e_, t_) almightyCC = CHERICCCap {
|
||||||
// isCap: True,
|
isCap: True,
|
||||||
// softperms: ~0,
|
softperms: ~0,
|
||||||
// hardperms: unpack(~0),
|
hardperms: unpack(~0),
|
||||||
// res: 0,
|
res: 0,
|
||||||
// bounds: EmbeddedExp {
|
bounds: EmbeddedExp {
|
||||||
// top: 0, // implied top bits of 01
|
top: 0, // implied top bits of 01
|
||||||
// base: 0,
|
base: 0,
|
||||||
// // position the 1 of top in the addr_'th bit
|
// position the 1 of top in the addr_'th bit
|
||||||
// e: fromInteger(`i(addr_)-((`i(bounds_)/2)-2))
|
e: fromInteger(`i(addr_)-((`i(bounds_)/2)-2))
|
||||||
// },
|
},
|
||||||
// addr: 0
|
addr: 0
|
||||||
// };
|
};
|
||||||
|
|
||||||
// CHERICCCap#(addr_, bounds_, e_, t_) nullCC = CHERICCCap {
|
CHERICCCap#(addr_, bounds_, e_, t_) nullCC = CHERICCCap {
|
||||||
// isCap: False,
|
isCap: False,
|
||||||
// softperms: 0,
|
softperms: 0,
|
||||||
// hardperms: unpack(0),
|
hardperms: unpack(0),
|
||||||
// res: 0,
|
res: 0,
|
||||||
// bounds: EmbeddedExp {
|
bounds: EmbeddedExp {
|
||||||
// top: 0, // implied top bits of 01
|
top: 0, // implied top bits of 01
|
||||||
// base: 0,
|
base: 0,
|
||||||
// e: fromInteger(`i(addr_)-((`i(bounds_)/2)-2)) // position the 1 of top in the addr_'th bit
|
e: fromInteger(`i(addr_)-((`i(bounds_)/2)-2)) // position the 1 of top in the addr_'th bit
|
||||||
// },
|
},
|
||||||
// addr: 0
|
addr: 0
|
||||||
// };
|
};
|
||||||
|
|
||||||
// function Bit#(e_) getExpCC(CHERICCCap#(addr_, bounds_, e_, t_) cap);
|
function Bit#(e_) getExpCC(CHERICCCap#(addr_, bounds_, e_, t_) cap);
|
||||||
// case (cap.bounds) matches
|
case (cap.bounds) matches
|
||||||
// tagged Exp0 .b: return 0;
|
tagged Exp0 .b: return 0;
|
||||||
// tagged EmbeddedExp .b: return b.e;
|
tagged EmbeddedExp .b: return b.e;
|
||||||
// tagged Sealed .b: return b.e;
|
tagged Sealed .b: return b.e;
|
||||||
// endcase
|
endcase
|
||||||
// endfunction
|
endfunction
|
||||||
|
|
||||||
// function Bit#(3) getRepBoundCC(CHERICCCap#(addr_, bounds_, e_, t_) cap)
|
function Bit#(3) getRepBoundCC(CHERICCCap#(addr_, bounds_, e_, t_) cap)
|
||||||
// provisos (Add#(3, a__, `div2(bounds_))) =
|
provisos (Add#(3, a__, `div2(bounds_))) =
|
||||||
// truncateLSB(cap.bounds.Exp0.base) - 3'b001; // always 1/8th of representable space below object
|
truncateLSB(cap.bounds.Exp0.base) - 3'b001; // always 1/8th of representable space below object
|
||||||
|
|
||||||
// function Int#(2) getRegionCorrectionCC(Bit#(3) a, Bit#(3) b, Bit#(3) rep) =
|
function Int#(2) getRegionCorrectionCC(Bit#(3) a, Bit#(3) b, Bit#(3) rep) =
|
||||||
// ((b < rep) == (a < rep)) ? 0 : (((b < rep) && (a >= rep)) ? 1 : -1);
|
((b < rep) == (a < rep)) ? 0 : (((b < rep) && (a >= rep)) ? 1 : -1);
|
||||||
|
|
||||||
// function Bit#(`div2(bounds_))
|
function Bit#(`div2(bounds_))
|
||||||
// getTopFieldCC(CHERICCCap#(addr_, bounds_, e_, t_) cap);
|
getTopFieldCC(CHERICCCap#(addr_, bounds_, e_, t_) cap);
|
||||||
// Bit#(2) c_carry = 2'b00;
|
Bit#(2) c_carry = 2'b00;
|
||||||
// Bit#(2) c_len = 2'b01;
|
Bit#(2) c_len = 2'b01;
|
||||||
// Bit#(`sub2(`div2(bounds_))) partialTop = 0;
|
Bit#(`sub2(`div2(bounds_))) partialTop = 0;
|
||||||
// case (cap.bounds) matches
|
case (cap.bounds) matches
|
||||||
// tagged Exp0 .b: begin
|
tagged Exp0 .b: begin
|
||||||
// if (zeroExtend(b.top) < b.base) c_carry = 2'b01;
|
if (zeroExtend(b.top) < b.base) c_carry = 2'b01;
|
||||||
// c_len = {1'b0, b.lenMSB};
|
c_len = {1'b0, b.lenMSB};
|
||||||
// partialTop = b.top;
|
partialTop = b.top;
|
||||||
// end
|
end
|
||||||
// tagged EmbeddedExp .b: begin
|
tagged EmbeddedExp .b: begin
|
||||||
// if (zeroExtend(b.top) < b.base) c_carry = 2'b01;
|
if (zeroExtend(b.top) < b.base) c_carry = 2'b01;
|
||||||
// partialTop = {b.top, 0};
|
partialTop = {b.top, 0};
|
||||||
// end
|
end
|
||||||
// tagged Sealed .b: begin
|
tagged Sealed .b: begin
|
||||||
// if (zeroExtend(b.top) < b.base) c_carry = 2'b01;
|
if (zeroExtend(b.top) < b.base) c_carry = 2'b01;
|
||||||
// partialTop = {b.top, 0};
|
partialTop = {b.top, 0};
|
||||||
// end
|
end
|
||||||
// endcase
|
endcase
|
||||||
// return {truncateLSB(cap.bounds.Exp0.base) + c_carry + c_len, partialTop};
|
return {truncateLSB(cap.bounds.Exp0.base) + c_carry + c_len, partialTop};
|
||||||
// endfunction
|
endfunction
|
||||||
|
|
||||||
// function Bit#(`div2(bounds_))
|
function Bit#(`div2(bounds_))
|
||||||
// getBaseFieldCC(CHERICCCap#(addr_, bounds_, e_, t_) cap) =
|
getBaseFieldCC(CHERICCCap#(addr_, bounds_, e_, t_) cap) =
|
||||||
// case (cap.bounds) matches
|
case (cap.bounds) matches
|
||||||
// tagged Exp0 .b: b.base;
|
tagged Exp0 .b: b.base;
|
||||||
// tagged EmbeddedExp .b: {b.base, 0};
|
tagged EmbeddedExp .b: {b.base, 0};
|
||||||
// tagged Sealed .b: {b.base, 0};
|
tagged Sealed .b: {b.base, 0};
|
||||||
// endcase;
|
endcase;
|
||||||
|
|
||||||
// // CHERICCCap CHERICap instance
|
// CHERICCCap CHERICap instance
|
||||||
// ////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// instance CHERICap#(CHERICCCap#(addr_, bounds_, e_, t_), t_, addr_) provisos (
|
instance CHERICap#(CHERICCCap#(addr_, bounds_, e_, t_), t_, addr_) provisos (
|
||||||
// Add#(3, a__, `div2(bounds_)), // 3 bits of bounds for 1/8th of rep space
|
Add#(3, a__, `div2(bounds_)), // 3 bits of bounds for 1/8th of rep space
|
||||||
// Add#(3, b__, addr_), // same for addr
|
Add#(3, b__, addr_), // same for addr
|
||||||
// Add#(c__, TAdd#(2, `div2(bounds_)), addr_), // for base correction
|
Add#(c__, TAdd#(2, `div2(bounds_)), addr_), // for base correction
|
||||||
// Add#(d__, TAdd#(2, `div2(bounds_)), TAdd#(addr_, 1)), // for top 2 bits of Int#(2) correction
|
Add#(d__, TAdd#(2, `div2(bounds_)), TAdd#(addr_, 1)), // for top 2 bits of Int#(2) correction
|
||||||
// Add#(e__, `div2(bounds_), addr_), // slice addr into smaller bounds field
|
Add#(e__, `div2(bounds_), addr_), // slice addr into smaller bounds field
|
||||||
// Add#(f__, `div2(bounds_), TAdd#(addr_, 1)), // same for addr+1
|
Add#(f__, `div2(bounds_), TAdd#(addr_, 1)), // same for addr+1
|
||||||
// Add#(g__, e_, TLog#(TAdd#(1, addr_))) // can fit result of countZerosMSB in e_
|
Add#(g__, e_, TLog#(TAdd#(1, addr_))) // can fit result of countZerosMSB in e_
|
||||||
// );
|
);
|
||||||
// //////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// function isValidCap(cap) = cap.isCap;
|
function isValidCap(cap) = cap.isCap;
|
||||||
// //////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// function setValidCap(cap, v);
|
function setValidCap(cap, v);
|
||||||
// cap.isCap = v;
|
cap.isCap = v;
|
||||||
// return cap;
|
return cap;
|
||||||
// endfunction
|
endfunction
|
||||||
// //////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// function getHardPerms(cap) = cap.hardperms;
|
function getHardPerms(cap) = cap.hardperms;
|
||||||
// //////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// function setHardPerms(cap, hardperms);
|
function setHardPerms(cap, hardperms);
|
||||||
// cap.hardperms = hardperms;
|
cap.hardperms = hardperms;
|
||||||
// return cap;
|
return cap;
|
||||||
// endfunction
|
endfunction
|
||||||
// //////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// function getSoftPerms(cap) = zeroExtend(cap.softperms);
|
function getSoftPerms(cap) = zeroExtend(cap.softperms);
|
||||||
// //////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// function setSoftPerms(cap, softperms);
|
function setSoftPerms(cap, softperms);
|
||||||
// cap.softperms = truncate(softperms);
|
cap.softperms = truncate(softperms);
|
||||||
// return cap;
|
return cap;
|
||||||
// endfunction
|
endfunction
|
||||||
// //////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// function getKind(cap) = case (cap.bounds) matches
|
function getKind(cap) = case (cap.bounds) matches
|
||||||
// tagged Sealed ._: return SEALED_WITH_TYPE;
|
tagged Sealed ._: return SEALED_WITH_TYPE;
|
||||||
// default: return UNSEALED;
|
default: return UNSEALED;
|
||||||
// endcase;
|
endcase;
|
||||||
// //////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// function getType(cap) = case (cap.bounds) matches
|
function getType(cap) = case (cap.bounds) matches
|
||||||
// tagged Sealed .b: return zeroExtend(b.otype);
|
tagged Sealed .b: return zeroExtend(b.otype);
|
||||||
// default: return -1;
|
default: return -1;
|
||||||
// endcase;
|
endcase;
|
||||||
// //////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// function setType(cap, otype);
|
function setType(cap, otype);
|
||||||
// let new_cap = cap;
|
let new_cap = cap;
|
||||||
// let isExact = True;
|
let isExact = True;
|
||||||
// case (cap.bounds) matches
|
case (cap.bounds) matches
|
||||||
// tagged Sealed .b: if (otype == -1) begin
|
tagged Sealed .b: if (otype == -1) begin
|
||||||
// //Bit#(addr_) addrBits = cap.address >> b.e;
|
//Bit#(addr_) addrBits = cap.address >> b.e;
|
||||||
// //let baseMid = addrBits[`sub1(TAdd#(`div2(t_), `div2(e))):`div2(e_)];
|
//let baseMid = addrBits[`sub1(TAdd#(`div2(t_), `div2(e))):`div2(e_)];
|
||||||
// //let baseLo = addrBits[`sub1(`div2(e_)):0];
|
//let baseLo = addrBits[`sub1(`div2(e_)):0];
|
||||||
// //let topMid = baseMid;
|
//let topMid = baseMid;
|
||||||
// //let topLo = baseLo;
|
//let topLo = baseLo;
|
||||||
// let baseHi = b.base;
|
let baseHi = b.base;
|
||||||
// let topHi = b.top;
|
let topHi = b.top;
|
||||||
// if (b.e == 0) new_cap.bounds = Exp0 {
|
if (b.e == 0) new_cap.bounds = Exp0 {
|
||||||
// lenMSB: 1,
|
lenMSB: 1,
|
||||||
// top: {topHi, 0},
|
top: {topHi, 0},
|
||||||
// base: {baseHi, 0}
|
base: {baseHi, 0}
|
||||||
// };
|
};
|
||||||
// else new_cap.bounds = EmbeddedExp {
|
else new_cap.bounds = EmbeddedExp {
|
||||||
// top: {topHi, 0},
|
top: {topHi, 0},
|
||||||
// base: {baseHi, 0},
|
base: {baseHi, 0},
|
||||||
// e: b.e
|
e: b.e
|
||||||
// };
|
};
|
||||||
// end
|
end
|
||||||
// default: if (otype != -1) begin
|
default: if (otype != -1) begin
|
||||||
// Bit#(e_) new_e = case (cap.bounds) matches
|
Bit#(e_) new_e = case (cap.bounds) matches
|
||||||
// tagged EmbeddedExp .b: b.e;
|
tagged EmbeddedExp .b: b.e;
|
||||||
// default: 0;
|
default: 0;
|
||||||
// endcase;
|
endcase;
|
||||||
// new_cap.bounds = Sealed {
|
new_cap.bounds = Sealed {
|
||||||
// top: truncateLSB(cap.bounds.Exp0.top),
|
top: truncateLSB(cap.bounds.Exp0.top),
|
||||||
// base: truncateLSB(cap.bounds.Exp0.base),
|
base: truncateLSB(cap.bounds.Exp0.base),
|
||||||
// otype: otype,
|
otype: otype,
|
||||||
// e: new_e
|
e: new_e
|
||||||
// };
|
};
|
||||||
// Bit#(`div2(t_)) zero = 0;
|
Bit#(`div2(t_)) zero = 0;
|
||||||
// isExact = cap.bounds.Exp0.top[`i(t_)/2-1:0] == zero &&
|
isExact = cap.bounds.Exp0.top[`i(t_)/2-1:0] == zero &&
|
||||||
// cap.bounds.Exp0.base[`i(t_)/2-1:0] == zero;
|
cap.bounds.Exp0.base[`i(t_)/2-1:0] == zero;
|
||||||
// end
|
end
|
||||||
// endcase
|
endcase
|
||||||
// return Exact{exact: isExact, value: new_cap};
|
return Exact{exact: isExact, value: new_cap};
|
||||||
// endfunction
|
endfunction
|
||||||
// //////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// function getAddr(cap) = cap.addr;
|
function getAddr(cap) = cap.addr;
|
||||||
// //////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// function setAddr(cap) = error("setAddr unimplemented");
|
function setAddr(cap) = error("setAddr unimplemented");
|
||||||
// //////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// function getOffset(cap) = zeroExtend(getAddr(cap)) - getBase(cap);
|
function getOffset(cap) = zeroExtend(getAddr(cap)) - getBase(cap);
|
||||||
// //////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// function setOffset(cap, offset);
|
function setOffset(cap, offset);
|
||||||
// Bit#(`div2(bounds_)) e0m = ~(~0 << ((`i(t_)/2)+(`i(e_)/2)));
|
Bit#(`div2(bounds_)) e0m = ~(~0 << ((`i(t_)/2)+(`i(e_)/2)));
|
||||||
// Bit#(TSub#(`div2(bounds_), `div2(e_))) eem = ~(~0 << (`i(t_)/2));
|
Bit#(TSub#(`div2(bounds_), `div2(e_))) eem = ~(~0 << (`i(t_)/2));
|
||||||
// // extract specific useful values
|
// extract specific useful values
|
||||||
// Bit#(e_) e = getExpCC(cap);
|
Bit#(e_) e = getExpCC(cap);
|
||||||
// Bit#(e_) almighty_e = fromInteger(`i(addr_)-((`i(bounds_)/2)-2)); // position the 1 of top in the addr_'th bit
|
Bit#(e_) almighty_e = fromInteger(`i(addr_)-((`i(bounds_)/2)-2)); // position the 1 of top in the addr_'th bit
|
||||||
// Bit#(addr_) i = offset - getOffset(cap);
|
Bit#(addr_) i = offset - getOffset(cap);
|
||||||
// Bit#(`div2(bounds_)) imid = truncate(i >> e);
|
Bit#(`div2(bounds_)) imid = truncate(i >> e);
|
||||||
// Bit#(`div2(bounds_)) amid = truncate(cap.addr >> e);
|
Bit#(`div2(bounds_)) amid = truncate(cap.addr >> e);
|
||||||
// Bit#(`div2(bounds_)) r = {getRepBoundCC(cap), 0};
|
Bit#(`div2(bounds_)) r = {getRepBoundCC(cap), 0};
|
||||||
// // perform inRange and inLimit tests
|
// perform inRange and inLimit tests
|
||||||
// Bit#(addr_) mask = ~0 << (e + fromInteger(`i(bounds_)/2));
|
Bit#(addr_) mask = ~0 << (e + fromInteger(`i(bounds_)/2));
|
||||||
// Bool inRange = ((i & mask) == mask) || ((i & mask) == 0);
|
Bool inRange = ((i & mask) == mask) || ((i & mask) == 0);
|
||||||
// Bool inLimits = (i >= 0) ? imid < (r - amid - 1) :
|
Bool inLimits = (i >= 0) ? imid < (r - amid - 1) :
|
||||||
// imid >= (r - amid) && r != amid;
|
imid >= (r - amid) && r != amid;
|
||||||
// Bool isExact = ((inRange && inLimits) || e >= almighty_e);
|
Bool isExact = ((inRange && inLimits) || e >= almighty_e);
|
||||||
// // perform the offset update
|
// perform the offset update
|
||||||
// let new_cap = cap;
|
let new_cap = cap;
|
||||||
// new_cap.addr = truncate(getBase(cap) + offset);
|
new_cap.addr = truncate(getBase(cap) + offset);
|
||||||
// return Exact{exact: isExact, value: new_cap};
|
return Exact{exact: isExact, value: new_cap};
|
||||||
// endfunction
|
endfunction
|
||||||
// //////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// function getBase(cap);
|
function getBase(cap);
|
||||||
// let baseCC = getBaseFieldCC(cap);
|
let baseCC = getBaseFieldCC(cap);
|
||||||
// let e = getExpCC(cap);
|
let e = getExpCC(cap);
|
||||||
// let correction = getRegionCorrectionCC(truncateLSB(cap.addr),
|
let correction = getRegionCorrectionCC(truncateLSB(cap.addr),
|
||||||
// truncateLSB(baseCC),
|
truncateLSB(baseCC),
|
||||||
// getRepBoundCC(cap));
|
getRepBoundCC(cap));
|
||||||
// Bit#(addr_) mask = ~0 << (e + fromInteger(`i(bounds_)/2));
|
Bit#(addr_) mask = ~0 << (e + fromInteger(`i(bounds_)/2));
|
||||||
// Bit#(addr_) acc = cap.addr & mask;
|
Bit#(addr_) acc = cap.addr & mask;
|
||||||
// return acc + (signExtend({pack(correction), baseCC}) << e);
|
return acc + (signExtend({pack(correction), baseCC}) << e);
|
||||||
// endfunction
|
endfunction
|
||||||
// //////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// function getTop(cap);
|
function getTop(cap);
|
||||||
// let topCC = getTopFieldCC(cap);
|
let topCC = getTopFieldCC(cap);
|
||||||
// let e = getExpCC(cap);
|
let e = getExpCC(cap);
|
||||||
// let correction = getRegionCorrectionCC(truncateLSB(cap.addr),
|
let correction = getRegionCorrectionCC(truncateLSB(cap.addr),
|
||||||
// truncateLSB(topCC),
|
truncateLSB(topCC),
|
||||||
// getRepBoundCC(cap));
|
getRepBoundCC(cap));
|
||||||
// Bit#(TAdd#(addr_, 1)) mask = ~0 << (e + fromInteger(`i(bounds_)/2));
|
Bit#(TAdd#(addr_, 1)) mask = ~0 << (e + fromInteger(`i(bounds_)/2));
|
||||||
// Bit#(TAdd#(addr_, 1)) acc = zeroExtend(cap.addr) & mask;
|
Bit#(TAdd#(addr_, 1)) acc = zeroExtend(cap.addr) & mask;
|
||||||
// return acc + (signExtend({pack(correction), topCC}) << e);
|
return acc + (signExtend({pack(correction), topCC}) << e);
|
||||||
// endfunction
|
endfunction
|
||||||
// //////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// function getLength(cap) = getTop(cap) - zeroExtend(getBase(cap));
|
function getLength(cap) = getTop(cap) - zeroExtend(getBase(cap));
|
||||||
// //////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// function setBounds(cap, length);
|
function setBounds(cap, length);
|
||||||
// let new_cap = cap;
|
let new_cap = cap;
|
||||||
// let isExact = True;
|
let isExact = True;
|
||||||
// // deriving new exponent
|
// deriving new exponent
|
||||||
// Bit#(TLog#(TAdd#(1, addr_))) e =
|
Bit#(TLog#(TAdd#(1, addr_))) e =
|
||||||
// pack(fromInteger(`i(addr_))
|
pack(fromInteger(`i(addr_))
|
||||||
// - countZerosMSB(length >> ((`i(bounds_)/2)-1)));
|
- countZerosMSB(length >> ((`i(bounds_)/2)-1)));
|
||||||
// // deriving the new base
|
// deriving the new base
|
||||||
// Bit#(`div2(bounds_)) newBase = truncate(cap.addr >> e);
|
Bit#(`div2(bounds_)) newBase = truncate(cap.addr >> e);
|
||||||
// // deriving the new top
|
// deriving the new top
|
||||||
// Bit#(TAdd#(addr_, 1)) fullTop = zeroExtend(cap.addr) + zeroExtend(length);
|
Bit#(TAdd#(addr_, 1)) fullTop = zeroExtend(cap.addr) + zeroExtend(length);
|
||||||
// Bit#(`div2(bounds_)) newTop = truncate(fullTop >> e);
|
Bit#(`div2(bounds_)) newTop = truncate(fullTop >> e);
|
||||||
// // fold the derived values back in the new cap
|
// fold the derived values back in the new cap
|
||||||
// if (e == 0) begin
|
if (e == 0) begin
|
||||||
// new_cap.bounds = Exp0 {
|
new_cap.bounds = Exp0 {
|
||||||
// lenMSB: length[(`i(bounds_)/2)-2],
|
lenMSB: length[(`i(bounds_)/2)-2],
|
||||||
// top: truncate(newTop),
|
top: truncate(newTop),
|
||||||
// base: newBase
|
base: newBase
|
||||||
// };
|
};
|
||||||
// end else begin
|
end else begin
|
||||||
// // slice the top and base values appropriately
|
// slice the top and base values appropriately
|
||||||
// Bit#(TSub#(`sub2(`div2(bounds_)), `div2(e_))) upperTop = truncateLSB(newTop);
|
Bit#(TSub#(`sub2(`div2(bounds_)), `div2(e_))) upperTop = truncateLSB(newTop);
|
||||||
// Bit#(TSub#(`div2(bounds_), `div2(e_))) upperBase = truncateLSB(newBase);
|
Bit#(TSub#(`div2(bounds_), `div2(e_))) upperBase = truncateLSB(newBase);
|
||||||
// // take care of loss of significant bits in the bits stolen/dropped from fullTop
|
// take care of loss of significant bits in the bits stolen/dropped from fullTop
|
||||||
// Bit#(TAdd#(addr_, 1)) mask = ~(~0 << (e + fromInteger(`i(e_)/2)));
|
Bit#(TAdd#(addr_, 1)) mask = ~(~0 << (e + fromInteger(`i(e_)/2)));
|
||||||
// if ((fullTop & mask) != 0) upperTop = upperTop + 1;
|
if ((fullTop & mask) != 0) upperTop = upperTop + 1;
|
||||||
// new_cap.bounds = EmbeddedExp {
|
new_cap.bounds = EmbeddedExp {
|
||||||
// top: upperTop,
|
top: upperTop,
|
||||||
// base: upperBase,
|
base: upperBase,
|
||||||
// e: truncate(e)
|
e: truncate(e)
|
||||||
// };
|
};
|
||||||
// // check for exact or not
|
// check for exact or not
|
||||||
// Bit#(addr_) exactMask = ~(~0 << (e - fromInteger(`i(bounds_)/2 - `i(e_)/2 - 1)));
|
Bit#(addr_) exactMask = ~(~0 << (e - fromInteger(`i(bounds_)/2 - `i(e_)/2 - 1)));
|
||||||
// if ((cap.addr & exactMask) != 0) isExact = False;
|
if ((cap.addr & exactMask) != 0) isExact = False;
|
||||||
// if ((length & exactMask) != 0) isExact = False;
|
if ((length & exactMask) != 0) isExact = False;
|
||||||
// end
|
end
|
||||||
// return Exact{exact: isExact, value: new_cap};
|
return Exact{exact: isExact, value: new_cap};
|
||||||
// endfunction
|
endfunction
|
||||||
// //////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// function nullWithAddr(x);
|
function nullWithAddr(x);
|
||||||
// let cap = nullCap;
|
let cap = nullCap;
|
||||||
// cap.addr = x;
|
cap.addr = x;
|
||||||
// return cap;
|
return cap;
|
||||||
// endfunction
|
endfunction
|
||||||
// //////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// function almightyCap = almightyCC;
|
function almightyCap = almightyCC;
|
||||||
// //////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// function nullCap = nullCC;
|
function nullCap = nullCC;
|
||||||
// //////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// endinstance
|
endinstance
|
||||||
|
|
||||||
// `undef div2
|
`undef div2
|
||||||
// `undef sub2
|
`undef sub2
|
||||||
// `undef i
|
`undef i
|
||||||
|
|
||||||
// endpackage
|
endpackage
|
||||||
|
|||||||
179
CHERICC_Fat.bsv
179
CHERICC_Fat.bsv
@@ -37,11 +37,13 @@ export CapMem;
|
|||||||
export CapReg;
|
export CapReg;
|
||||||
export CapPipe;
|
export CapPipe;
|
||||||
|
|
||||||
|
export encodeDelta;
|
||||||
|
export addDelta;
|
||||||
|
export decodeDelta;
|
||||||
|
|
||||||
export CapFat;
|
export CapFat;
|
||||||
export MW;
|
export MW;
|
||||||
export OTypeW;
|
export OTypeW;
|
||||||
export Delta;
|
|
||||||
export setDeltaValue;
|
|
||||||
export FlagsW;
|
export FlagsW;
|
||||||
export Perms;
|
export Perms;
|
||||||
export ResW;
|
export ResW;
|
||||||
@@ -61,8 +63,8 @@ export Exp;
|
|||||||
export MetaInfo;
|
export MetaInfo;
|
||||||
export SetBoundsReturn;
|
export SetBoundsReturn;
|
||||||
export CapTrim;
|
export CapTrim;
|
||||||
// export trimCap;
|
export trimCap;
|
||||||
// export untrimCap;
|
export untrimCap;
|
||||||
export CapAddr;
|
export CapAddr;
|
||||||
export CapAddrPlus1;
|
export CapAddrPlus1;
|
||||||
|
|
||||||
@@ -86,20 +88,20 @@ typedef 0 UPermW;
|
|||||||
typedef 8 MW;
|
typedef 8 MW;
|
||||||
typedef 6 ExpW;
|
typedef 6 ExpW;
|
||||||
typedef 4 OTypeW;
|
typedef 4 OTypeW;
|
||||||
typedef 24 Delta;
|
// typedef 24 Delta;
|
||||||
typedef `FLAGSW FlagsW;
|
typedef `FLAGSW FlagsW;
|
||||||
typedef 32 CapAddrW;
|
typedef 32 CapAddrW;
|
||||||
typedef 88 CapW;
|
typedef 64 CapW;
|
||||||
`else // CAP128 is default
|
`else // CAP128 is default
|
||||||
typedef 4 UPermW;
|
typedef 4 UPermW;
|
||||||
typedef 14 MW;
|
typedef 14 MW;
|
||||||
typedef 6 ExpW;
|
typedef 6 ExpW;
|
||||||
typedef 18 OTypeW;
|
typedef 18 OTypeW;
|
||||||
typedef 52 Delta;
|
// typedef 44 Delta;
|
||||||
typedef `FLAGSW FlagsW;
|
typedef `FLAGSW FlagsW;
|
||||||
typedef 64 CapAddrW;
|
typedef 64 CapAddrW;
|
||||||
// The capability width changes
|
// The capability width changes
|
||||||
typedef 180 CapW;
|
typedef 128 CapW;
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
// The Address type is used to represent the full sized address returned to the
|
// The Address type is used to represent the full sized address returned to the
|
||||||
@@ -144,9 +146,8 @@ typedef SizeOf#(Perms) PermsW;
|
|||||||
// The reserved bits
|
// The reserved bits
|
||||||
typedef TSub#(CapW, TAdd#( CapAddrW
|
typedef TSub#(CapW, TAdd#( CapAddrW
|
||||||
, TAdd#( OTypeW
|
, TAdd#( OTypeW
|
||||||
, TAdd#( Delta
|
|
||||||
, TAdd#( CBoundsW
|
, TAdd#( CBoundsW
|
||||||
, TAdd#(PermsW, FlagsW)))))) ResW;
|
, TAdd#(PermsW, FlagsW))))) ResW;
|
||||||
// The full capability structure, including the "tag" bit.
|
// The full capability structure, including the "tag" bit.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Bool isCapability;
|
Bool isCapability;
|
||||||
@@ -154,15 +155,14 @@ typedef struct {
|
|||||||
Bit#(ResW) reserved;
|
Bit#(ResW) reserved;
|
||||||
Bit#(FlagsW) flags;
|
Bit#(FlagsW) flags;
|
||||||
Bit#(OTypeW) otype;
|
Bit#(OTypeW) otype;
|
||||||
Bit#(Delta) delta;
|
// Bit#(Delta) delta;
|
||||||
CBounds bounds;
|
CBounds bounds;
|
||||||
CapAddr address;
|
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.
|
// The full capability structure as Bits, including the "tag" bit.
|
||||||
typedef Bit#(TAdd#(CapW,1)) Capability;
|
typedef Bit#(TAdd#(CapW,1)) Capability;
|
||||||
// not including the tag bit
|
// not including the tag bit
|
||||||
// Hard-coded
|
typedef Bit#(CapW) CapBits;
|
||||||
typedef Bit#(128) CapBits;
|
|
||||||
/* TODO
|
/* TODO
|
||||||
staticAssert(valueOf(SizeOf#(CapabilityInMemory))==valueOf(SizeOf#(Capability)),
|
staticAssert(valueOf(SizeOf#(CapabilityInMemory))==valueOf(SizeOf#(Capability)),
|
||||||
"The CapabilityInMemory type has incorrect size of " + integerToString(valueOf(SizeOf#(CapabilityInMemory))) + " (CapW = " + integerToString(valueOf(CapW)) + ")"
|
"The CapabilityInMemory type has incorrect size of " + integerToString(valueOf(SizeOf#(CapabilityInMemory))) + " (CapW = " + integerToString(valueOf(CapW)) + ")"
|
||||||
@@ -191,7 +191,7 @@ typedef struct {
|
|||||||
Bit#(FlagsW) flags;
|
Bit#(FlagsW) flags;
|
||||||
Bit#(ResW) reserved;
|
Bit#(ResW) reserved;
|
||||||
Bit#(OTypeW) otype;
|
Bit#(OTypeW) otype;
|
||||||
Bit#(Delta) delta;
|
// Bit#(Delta) delta;
|
||||||
Format format;
|
Format format;
|
||||||
Bounds bounds;
|
Bounds bounds;
|
||||||
} CapFat deriving (Bits);
|
} CapFat deriving (Bits);
|
||||||
@@ -238,7 +238,7 @@ function CapFat unpackCap(Capability thin);
|
|||||||
fat.flags = memCap.flags;
|
fat.flags = memCap.flags;
|
||||||
fat.reserved = memCap.reserved;
|
fat.reserved = memCap.reserved;
|
||||||
fat.otype = memCap.otype;
|
fat.otype = memCap.otype;
|
||||||
fat.delta = memCap.delta;
|
// fat.delta = memCap.delta;
|
||||||
match {.f, .b} = decBounds(memCap.bounds);
|
match {.f, .b} = decBounds(memCap.bounds);
|
||||||
fat.format = f;
|
fat.format = f;
|
||||||
fat.bounds = b;
|
fat.bounds = b;
|
||||||
@@ -262,7 +262,6 @@ function Capability packCap(CapFat fat);
|
|||||||
, flags: fat.flags
|
, flags: fat.flags
|
||||||
, reserved: fat.reserved
|
, reserved: fat.reserved
|
||||||
, otype: fat.otype
|
, otype: fat.otype
|
||||||
, delta: fat.delta
|
|
||||||
, bounds: encBounds(fat.format,fat.bounds)
|
, bounds: encBounds(fat.format,fat.bounds)
|
||||||
, address: fat.address };
|
, address: fat.address };
|
||||||
return pack(thin);
|
return pack(thin);
|
||||||
@@ -888,7 +887,6 @@ instance DefaultValue #(CapFat);
|
|||||||
, flags : 0
|
, flags : 0
|
||||||
, reserved : 0
|
, reserved : 0
|
||||||
, otype : otype_unsealed
|
, otype : otype_unsealed
|
||||||
, delta : 0
|
|
||||||
, format : EmbeddedExp
|
, format : EmbeddedExp
|
||||||
, bounds : defaultValue
|
, bounds : defaultValue
|
||||||
, address : 0
|
, address : 0
|
||||||
@@ -901,7 +899,6 @@ CapFat null_cap = CapFat {
|
|||||||
, flags : 0
|
, flags : 0
|
||||||
, reserved : 0
|
, reserved : 0
|
||||||
, otype : otype_unsealed
|
, otype : otype_unsealed
|
||||||
, delta : 0
|
|
||||||
, format : EmbeddedExp
|
, format : EmbeddedExp
|
||||||
, bounds : defaultValue
|
, bounds : defaultValue
|
||||||
, address : 0
|
, address : 0
|
||||||
@@ -1058,7 +1055,7 @@ typedef struct {
|
|||||||
// Note: commented out methods have a provided default implementation in the
|
// Note: commented out methods have a provided default implementation in the
|
||||||
// CHERICap typeclass definition
|
// CHERICap typeclass definition
|
||||||
|
|
||||||
instance CHERICap #(CapMem, OTypeW, FlagsW, CapAddrW, CapW, TSub #(MW, 3), Delta);
|
instance CHERICap #(CapMem, OTypeW, FlagsW, CapAddrW, CapW, TSub #(MW, 3));
|
||||||
|
|
||||||
// capability validity
|
// capability validity
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -1126,7 +1123,7 @@ instance CHERICap #(CapMem, OTypeW, FlagsW, CapAddrW, CapW, TSub #(MW, 3), Delta
|
|||||||
, pack (cap.reserved)
|
, pack (cap.reserved)
|
||||||
, pack (cap.flags)
|
, pack (cap.flags)
|
||||||
, pack (cap.otype)
|
, pack (cap.otype)
|
||||||
, pack (cap.delta)
|
// , pack (cap.delta)
|
||||||
, pack (cap.bounds) };
|
, pack (cap.bounds) };
|
||||||
endfunction
|
endfunction
|
||||||
function getAddr (capMem);
|
function getAddr (capMem);
|
||||||
@@ -1170,10 +1167,6 @@ instance CHERICap #(CapMem, OTypeW, FlagsW, CapAddrW, CapW, TSub #(MW, 3), Delta
|
|||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
function setBoundsCombined =
|
function setBoundsCombined =
|
||||||
error ("setBoundsCombined not implemented for CapMem");
|
error ("setBoundsCombined not implemented for CapMem");
|
||||||
|
|
||||||
// Create function to set delta value
|
|
||||||
function setDeltaValue (CapPipe cap, Bit#(Delta) delta) = error ("setDeltaValue not implemented for CapMem");
|
|
||||||
|
|
||||||
//function setBounds = error ("setBounds not implemented for CapMem");
|
//function setBounds = error ("setBounds not implemented for CapMem");
|
||||||
//function roundLength = error ("roundLength not implemented for CapMem");
|
//function roundLength = error ("roundLength not implemented for CapMem");
|
||||||
//function alignmentMask = error ("alignmentMask not implemented for CapMem");
|
//function alignmentMask = error ("alignmentMask not implemented for CapMem");
|
||||||
@@ -1192,6 +1185,10 @@ instance CHERICap #(CapMem, OTypeW, FlagsW, CapAddrW, CapW, TSub #(MW, 3), Delta
|
|||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
function isDerivable = error ("isDerivable not implemented for CapMem");
|
function isDerivable = error ("isDerivable not implemented for CapMem");
|
||||||
|
|
||||||
|
function encodeDelta (cap, delta) = error ("encode delta not implemented");
|
||||||
|
function addDelta (cap, delta) = error ("addDelta not implemented");
|
||||||
|
function decodeDelta (cap) = error ("decode delta not implemented");
|
||||||
|
|
||||||
endinstance
|
endinstance
|
||||||
|
|
||||||
instance FShow #(CapPipe);
|
instance FShow #(CapPipe);
|
||||||
@@ -1221,7 +1218,7 @@ endinstance
|
|||||||
// Note: commented out methods have a provided default implementation in the
|
// Note: commented out methods have a provided default implementation in the
|
||||||
// CHERICap typeclass definition
|
// CHERICap typeclass definition
|
||||||
|
|
||||||
instance CHERICap #(CapReg, OTypeW, FlagsW, CapAddrW, CapW, TSub #(MW, 3), Delta);
|
instance CHERICap #(CapReg, OTypeW, FlagsW, CapAddrW, CapW, TSub #(MW, 3));
|
||||||
|
|
||||||
// capability validity
|
// capability validity
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -1346,8 +1343,9 @@ instance CHERICap #(CapReg, OTypeW, FlagsW, CapAddrW, CapW, TSub #(MW, 3), Delta
|
|||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
function setBoundsCombined (cap, length) = error ("setBoundsCombined not implemented for CapReg");
|
function setBoundsCombined (cap, length) = error ("setBoundsCombined not implemented for CapReg");
|
||||||
|
|
||||||
// Create function to set delta value
|
function encodeDelta (cap, delta) = error ("encode delta not implemented");
|
||||||
function setDeltaValue (CapPipe cap, Bit#(Delta) delta) = error ("setDeltaValue not implemented for CapReg");
|
function addDelta (cap, delta) = error ("addDelta not implemented");
|
||||||
|
function decodeDelta (cap) = error ("decode delta not implemented");
|
||||||
|
|
||||||
//function setBounds = error ("setBounds not implemented for CapReg");
|
//function setBounds = error ("setBounds not implemented for CapReg");
|
||||||
//function roundLength = error ("roundLength not implemented for CapReg");
|
//function roundLength = error ("roundLength not implemented for CapReg");
|
||||||
@@ -1373,7 +1371,7 @@ instance CHERICap #(CapReg, OTypeW, FlagsW, CapAddrW, CapW, TSub #(MW, 3), Delta
|
|||||||
|
|
||||||
endinstance
|
endinstance
|
||||||
|
|
||||||
instance CHERICap #(CapPipe, OTypeW, FlagsW, CapAddrW, CapW, TSub#(MW, 3), Delta);
|
instance CHERICap #(CapPipe, OTypeW, FlagsW, CapAddrW, CapW, TSub#(MW, 3));
|
||||||
|
|
||||||
//Functions supported by CapReg are just passed through
|
//Functions supported by CapReg are just passed through
|
||||||
|
|
||||||
@@ -1421,21 +1419,36 @@ instance CHERICap #(CapPipe, OTypeW, FlagsW, CapAddrW, CapW, TSub#(MW, 3), Delta
|
|||||||
, mask: result.mask };
|
, mask: result.mask };
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
// Create function to set delta value
|
// TODO: Similar to set bounds but sets the delta value between the 38th and 64th bit
|
||||||
function setDeltaValue (CapPipe cap, Bit#(Delta) delta);
|
// function setDeltaValue (cap, length);
|
||||||
// let result = setDelta(cap.capFat, delta);
|
// endfunction
|
||||||
cap.capFat.delta = delta;
|
|
||||||
|
function encodeDelta(cap, delta);
|
||||||
|
// Make a test case of adding 3
|
||||||
|
Bit#(25) d = truncate(delta);
|
||||||
|
// d = 15;
|
||||||
|
Bit#(39) va_bits = cap.capFat.address[38:0];
|
||||||
|
cap.capFat.address = {d, va_bits};
|
||||||
|
return cap;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function addDelta(cap, delta);
|
||||||
|
Bit#(25) d = truncate(delta);
|
||||||
|
cap.capFat.address = cap.capFat.address + zeroExtend(delta);
|
||||||
return cap;
|
return cap;
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
// Extract the delta stored in bits 63:39 of the address
|
||||||
|
function decodeDelta(cap);
|
||||||
|
return cap.capFat.address[63:39];
|
||||||
|
endfunction
|
||||||
|
|
||||||
function nullWithAddr (addr);
|
function nullWithAddr (addr);
|
||||||
CapReg res = nullWithAddr(addr);
|
CapReg res = nullWithAddr(addr);
|
||||||
return CapPipe { capFat: res, tempFields: getTempFields(res) };
|
return CapPipe { capFat: res, tempFields: getTempFields(res) };
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
// A hack to fix compile time check
|
|
||||||
function fromMem (capBits);
|
function fromMem (capBits);
|
||||||
CapReg res = fromMem(capBits);
|
CapReg res = fromMem(capBits);
|
||||||
return CapPipe { capFat: res, tempFields: getTempFields(res) };
|
return CapPipe { capFat: res, tempFields: getTempFields(res) };
|
||||||
@@ -1451,18 +1464,10 @@ instance CHERICap #(CapPipe, OTypeW, FlagsW, CapAddrW, CapW, TSub#(MW, 3), Delta
|
|||||||
return CapPipe { capFat: res, tempFields: getTempFields(res) };
|
return CapPipe { capFat: res, tempFields: getTempFields(res) };
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Bit#(39) trueAddr;
|
|
||||||
Bit#(25) delta;
|
|
||||||
} MyAddr deriving (Bits);
|
|
||||||
|
|
||||||
//Functions that require TempFields
|
//Functions that require TempFields
|
||||||
|
|
||||||
function setAddr (cap, address);
|
function setAddr (cap, address);
|
||||||
// todo
|
let result = setAddress(cap.capFat, address, cap.tempFields);
|
||||||
MyAddr myAddr = unpack(pack(addr));
|
|
||||||
myAddr.delta = 42;
|
|
||||||
let result = setAddress(cap.capFat, pack(myAddr), cap.tempFields);
|
|
||||||
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 };
|
||||||
@@ -1565,48 +1570,62 @@ typedef 48 VA_Width;
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
Perms perms;
|
Perms perms;
|
||||||
Bit#(FlagsW) flags;
|
Bit#(FlagsW) flags;
|
||||||
Bit#(Delta) delta;
|
// Bit#(Delta) delta;
|
||||||
CBounds bounds;
|
CBounds bounds;
|
||||||
Bit#(VA_Width) address;
|
Bit#(VA_Width) address;
|
||||||
Bool validAddress;
|
Bool validAddress;
|
||||||
} CapTrim deriving(Bits, Eq, FShow);
|
} CapTrim deriving(Bits, Eq, FShow);
|
||||||
// function CapTrim trimCap(CapMem cm);
|
function CapTrim trimCap(CapMem cm);
|
||||||
// CapabilityInMemory cap = unpack(cm);
|
CapabilityInMemory cap = unpack(cm);
|
||||||
// Bit#(TSub#(CapAddrW,VA_Width)) addr_upper = truncateLSB(cap.address);
|
Bit#(TSub#(CapAddrW,VA_Width)) addr_upper = truncateLSB(cap.address);
|
||||||
// return CapTrim{perms: cap.perms,
|
return CapTrim{perms: cap.perms,
|
||||||
// flags: cap.flags,
|
flags: cap.flags,
|
||||||
// delta: cap.delta,
|
bounds: cap.bounds,
|
||||||
// bounds: cap.bounds,
|
address: truncate(cap.address),
|
||||||
// address: truncate(cap.address),
|
validAddress: (addr_upper==signExtend(cap.address[valueOf(VA_Width)-1]))
|
||||||
// validAddress: (addr_upper==signExtend(cap.address[valueOf(VA_Width)-1]))
|
};
|
||||||
// };
|
endfunction
|
||||||
// endfunction
|
function CapMem untrimCap(CapTrim ct);
|
||||||
// function CapMem untrimCap(CapTrim ct);
|
// Encode an invalid address as the bit above the last valid bit being different.
|
||||||
// // Encode an invalid address as the bit above the last valid bit being different.
|
Bit#(1) addressMsb = ct.address[valueOf(VA_Width)-1];
|
||||||
// Bit#(1) addressMsb = ct.address[valueOf(VA_Width)-1];
|
if (!ct.validAddress) addressMsb = ^addressMsb;
|
||||||
// if (!ct.validAddress) addressMsb = ^addressMsb;
|
return pack(CapabilityInMemory{
|
||||||
// return pack(CapabilityInMemory{
|
isCapability: True,
|
||||||
// isCapability: True,
|
perms: ct.perms,
|
||||||
// perms: ct.perms,
|
reserved: 0,
|
||||||
// reserved: 0,
|
flags: ct.flags,
|
||||||
// flags: ct.flags,
|
otype: otype_unsealed,
|
||||||
// otype: otype_unsealed,
|
bounds: ct.bounds,
|
||||||
// delta: ct.delta,
|
address: signExtend({addressMsb,ct.address})
|
||||||
// bounds: ct.bounds,
|
});
|
||||||
// address: signExtend({addressMsb,ct.address})
|
|
||||||
// });
|
|
||||||
// endfunction
|
|
||||||
|
|
||||||
// Standalone fromMem wrapper for CapPipe
|
|
||||||
function CapPipe fromMemTest(Tuple2#(Bool, Bit#(CapW)) capBits);
|
|
||||||
// capBits.fst = Bool tag
|
|
||||||
// capBits.snd = concatenated bits (e.g., {getAddr(b), getAddr(a)})
|
|
||||||
|
|
||||||
// Reconstruct the underlying CapReg (or CapFat)
|
|
||||||
CapReg res = fromMem(capBits);
|
|
||||||
|
|
||||||
// Wrap into CapPipe with tempFields
|
|
||||||
return CapPipe { capFat: res, tempFields: getTempFields(res) };
|
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
// We do not implement the functions as interfaces
|
||||||
|
// because all them will have the same implementation/
|
||||||
|
// This negates the purpose of having type classes.
|
||||||
|
// Create function to set delta value
|
||||||
|
// function setDeltaValue (CapPipe cap, Bit#(Delta) delta);
|
||||||
|
// // let result = setDelta(cap.capFat, delta);
|
||||||
|
// cap.capFat.delta = delta;
|
||||||
|
// return cap;
|
||||||
|
// endfunction
|
||||||
|
|
||||||
|
// typedef struct {
|
||||||
|
// CapFat capFat;
|
||||||
|
// TempFields tempFields;
|
||||||
|
// } CapPipe deriving (Bits);
|
||||||
|
|
||||||
|
// typedef struct {
|
||||||
|
// Bool isCapability;
|
||||||
|
// Bit#(CapAddrW) address;
|
||||||
|
// Bit#(MW) addrBits;
|
||||||
|
// Perms perms;
|
||||||
|
// Bit#(FlagsW) flags;
|
||||||
|
// Bit#(ResW) reserved;
|
||||||
|
// Bit#(OTypeW) otype;
|
||||||
|
// // Bit#(Delta) delta;
|
||||||
|
// Format format;
|
||||||
|
// Bounds bounds;
|
||||||
|
// } CapFat deriving (Bits);
|
||||||
|
|
||||||
endpackage
|
endpackage
|
||||||
|
|||||||
14
CHERICap.bsv
14
CHERICap.bsv
@@ -119,7 +119,7 @@ endfunction
|
|||||||
|
|
||||||
// XXX TODO augment with all architectural bounds/ repbounds ?
|
// XXX TODO augment with all architectural bounds/ repbounds ?
|
||||||
function Fmt showCHERICap (capT cap)
|
function Fmt showCHERICap (capT cap)
|
||||||
provisos (CHERICap #(capT , otypeW, flgW, addrW, inMemW, maskableW, delta));
|
provisos (CHERICap #(capT , otypeW, flgW, addrW, inMemW, maskableW));
|
||||||
return $format( "Valid: 0x%0x", isValidCap(cap)) +
|
return $format( "Valid: 0x%0x", isValidCap(cap)) +
|
||||||
$format(" Perms: 0x%0x", getPerms(cap)) +
|
$format(" Perms: 0x%0x", getPerms(cap)) +
|
||||||
$format(" Kind: ", fshow(getKind(cap))) +
|
$format(" Kind: ", fshow(getKind(cap))) +
|
||||||
@@ -153,9 +153,8 @@ typeclass CHERICap #( type capT // type of the CHERICap capability
|
|||||||
, numeric type addrW // width of the address
|
, numeric type addrW // width of the address
|
||||||
, numeric type inMemW // width of the capability in mem
|
, numeric type inMemW // width of the capability in mem
|
||||||
, numeric type maskableW // width of maskable bits
|
, numeric type maskableW // width of maskable bits
|
||||||
, numeric type delta // size of delta (tlb bypass)
|
|
||||||
)
|
)
|
||||||
dependencies (capT determines (otypeW, flgW, addrW, inMemW, maskableW, delta));
|
dependencies (capT determines (otypeW, flgW, addrW, inMemW, maskableW));
|
||||||
|
|
||||||
// capability validity
|
// capability validity
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -173,6 +172,11 @@ typeclass CHERICap #( type capT // type of the CHERICap capability
|
|||||||
// Set the flags field
|
// Set the flags field
|
||||||
function capT setFlags (capT cap, Bit #(flgW) flags);
|
function capT setFlags (capT cap, Bit #(flgW) flags);
|
||||||
|
|
||||||
|
function capT encodeDelta(capT cap, Bit #(64) delta);
|
||||||
|
function capT addDelta(capT cap, Bit #(25) delta);
|
||||||
|
|
||||||
|
function Bit #(25) decodeDelta(capT cap);
|
||||||
|
|
||||||
// capability permissions
|
// capability permissions
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -321,8 +325,8 @@ typeclass CHERICap #( type capT // type of the CHERICap capability
|
|||||||
// the null capability (requires a dummy proxy)
|
// the null capability (requires a dummy proxy)
|
||||||
function capT nullCapFromDummy (capT dummy);
|
function capT nullCapFromDummy (capT dummy);
|
||||||
|
|
||||||
// define set delta function
|
// define set delta function (Disabled when we will use the virtual addresses)
|
||||||
function capT setDeltaValue (capT cap, Bit #(delta) length);
|
// function capT setDeltaValue (capT cap, Bit #(delta) length);
|
||||||
|
|
||||||
// Assert that the encoding is valid
|
// Assert that the encoding is valid
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
// module assert_prop_unique(
|
module assert_prop_unique(
|
||||||
// input wire [63 : 0] prop_base,
|
input wire [63 : 0] prop_base,
|
||||||
// input wire [63 : 0] prop_len,
|
input wire [63 : 0] prop_len,
|
||||||
// input wire [63 : 0] prop_newBase,
|
input wire [63 : 0] prop_newBase,
|
||||||
// input wire [63 : 0] prop_newLen
|
input wire [63 : 0] prop_newLen
|
||||||
// );
|
);
|
||||||
// wire prop_ok;
|
wire prop_ok;
|
||||||
|
|
||||||
// module_prop_unique module_prop_unique_inst (
|
module_prop_unique module_prop_unique_inst (
|
||||||
// .prop_unique_base(prop_base),
|
.prop_unique_base(prop_base),
|
||||||
// .prop_unique_len(prop_len),
|
.prop_unique_len(prop_len),
|
||||||
// .prop_unique_newBase(prop_newBase),
|
.prop_unique_newBase(prop_newBase),
|
||||||
// .prop_unique_newLen(prop_newLen),
|
.prop_unique_newLen(prop_newLen),
|
||||||
// .prop_unique(prop_ok)
|
.prop_unique(prop_ok)
|
||||||
// );
|
);
|
||||||
|
|
||||||
// always @(*) begin
|
always @(*) begin
|
||||||
// assert(prop_ok);
|
assert(prop_ok);
|
||||||
// end
|
end
|
||||||
// endmodule
|
endmodule
|
||||||
|
|
||||||
module assert_prop_exact(
|
module assert_prop_exact(
|
||||||
input wire [63 : 0] prop_base,
|
input wire [63 : 0] prop_base,
|
||||||
@@ -180,4 +180,3 @@ module assert_prop_setBounds(
|
|||||||
always @(*) begin
|
always @(*) begin
|
||||||
assert(prop_ok);
|
assert(prop_ok);
|
||||||
end
|
end
|
||||||
endmodule
|
|
||||||
|
|||||||
Reference in New Issue
Block a user