summaryrefslogtreecommitdiff
path: root/cheri/cheri_prelude_common.sail
diff options
context:
space:
mode:
Diffstat (limited to 'cheri/cheri_prelude_common.sail')
-rw-r--r--cheri/cheri_prelude_common.sail63
1 files changed, 47 insertions, 16 deletions
diff --git a/cheri/cheri_prelude_common.sail b/cheri/cheri_prelude_common.sail
index d2b69de8..764a4ff1 100644
--- a/cheri/cheri_prelude_common.sail
+++ b/cheri/cheri_prelude_common.sail
@@ -374,29 +374,60 @@ function MEMw_conditional_wrapper(addr, size, data) =
success;
}
-val addrWrapper : (bits(64), MemAccessType, WordType) -> bits(64) effect {rreg, wreg, escape}
-function addrWrapper(addr, accessType, width) =
+val checkDDCPerms : (CapStruct, MemAccessType) -> unit effect {escape, rreg, wreg}
+function checkDDCPerms(ddc : CapStruct, accessType: MemAccessType) =
{
- capno = 0b00000;
- cap = readCapRegDDC(capno);
- if (not (cap.tag)) then
- (raise_c2_exception(CapEx_TagViolation, capno))
- else if (cap.sealed) then
- (raise_c2_exception(CapEx_SealViolation, capno));
+ if (not (ddc.tag)) then
+ raise_c2_exception(CapEx_TagViolation, 0b00000)
+ else if (ddc.sealed) then
+ raise_c2_exception(CapEx_SealViolation, 0b00000);
match accessType {
- Instruction => if (~(cap.permit_execute)) then (raise_c2_exception(CapEx_PermitExecuteViolation, capno)),
- LoadData => if (~(cap.permit_load)) then (raise_c2_exception(CapEx_PermitLoadViolation, capno)),
- StoreData => if (~(cap.permit_store)) then (raise_c2_exception(CapEx_PermitStoreViolation, capno))
+ Instruction => assert(false), /* Only data accesses use DDC */
+ LoadData => if (~(ddc.permit_load)) then (raise_c2_exception(CapEx_PermitLoadViolation, 0b00000)),
+ StoreData => if (~(ddc.permit_store)) then (raise_c2_exception(CapEx_PermitStoreViolation, 0b00000))
};
- cursor = getCapCursor(cap);
+ }
+
+val addrWrapper : (bits(64), MemAccessType, WordType) -> bits(64) effect {rreg, wreg, escape}
+function addrWrapper(addr, accessType, width) =
+ {
+ ddc = capRegToCapStruct(DDC);
+ checkDDCPerms(ddc, accessType);
+ cursor = getCapCursor(ddc);
vAddr = (cursor + unsigned(addr)) % pow2(64);
size = wordWidthBytes(width);
- base = getCapBase(cap);
- top = getCapTop(cap);
+ base = getCapBase(ddc);
+ top = getCapTop(ddc);
if ((vAddr + size) > top) then
- (raise_c2_exception(CapEx_LengthViolation, capno))
+ (raise_c2_exception(CapEx_LengthViolation, 0b00000))
else if (vAddr < base) then
- (raise_c2_exception(CapEx_LengthViolation, capno))
+ (raise_c2_exception(CapEx_LengthViolation, 0b00000))
+ else
+ to_bits(64, vAddr);
+ }
+
+val addrWrapperUnaligned : (bits(64), MemAccessType, WordTypeUnaligned) -> bits(64) effect {rreg, wreg, escape}
+function addrWrapperUnaligned(addr, accessType, width) =
+ {
+ ddc = capRegToCapStruct(DDC);
+ checkDDCPerms(ddc, accessType);
+ cursor = getCapCursor(ddc);
+ vAddr = (cursor + unsigned(addr)) % pow2(64);
+ woffset = vAddr % 4;
+ doffset = vAddr % 8;
+ /* Compute the address and size of the bytes touched -- this depends on alignment. */
+ let (waddr, size) : (int, int) = match width {
+ WL => (vAddr, 4 - woffset),
+ WR => (vAddr - woffset, woffset + 1),
+ DL => (vAddr, 8 - doffset),
+ DR => (vAddr - doffset, doffset + 1)
+ };
+ base = getCapBase(ddc);
+ top = getCapTop(ddc);
+ if ((waddr + size) > top) then
+ (raise_c2_exception(CapEx_LengthViolation, 0b00000))
+ else if (waddr < base) then
+ (raise_c2_exception(CapEx_LengthViolation, 0b00000))
else
to_bits(64, vAddr);
}