5 Commits

Author SHA1 Message Date
9d7de214d7 added add delta
Some checks failed
check properties / tests (push) Has been cancelled
2026-03-31 16:15:40 +01:00
6120b13246 pass through pointer works
Some checks failed
check properties / tests (push) Has been cancelled
2026-03-12 18:12:25 +00:00
3c6d203186 saving commented delta changes
Some checks failed
check properties / tests (push) Has been cancelled
2026-03-05 17:40:03 +00:00
6263041aa1 fixed removing areas where delta values were used
Some checks failed
check properties / tests (push) Has been cancelled
2026-02-23 12:26:03 +00:00
8f4feb2f1b removed delta values
Some checks failed
check properties / tests (push) Has been cancelled
2026-02-23 11:59:31 +00:00
4 changed files with 556 additions and 534 deletions

View File

@@ -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

View File

@@ -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; return cap;
endfunction endfunction
function addDelta(cap, delta);
Bit#(25) d = truncate(delta);
cap.capFat.address = cap.capFat.address + zeroExtend(delta);
return cap;
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

View File

@@ -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
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////

View File

@@ -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