@@ -933,7 +933,7 @@ function clause execute (CBuildCap(cd, cs1, cs2)) = {
933
933
RETIRE_FAIL
934
934
} else {
935
935
assert(exact, "CBuildCap: setCapBounds was not exact"); /* base and top came from cs2 originally so will be exact */
936
- let cd5 = if signed (cs2_val.otype) == otype_sentry then sealCap(cd4, to_bits(cap_otype_width, otype_sentry) ) else cd4;
936
+ let cd5 = if isCapSentryOrIsentry (cs2_val) then sealCap(cd4, cs2_val.otype ) else cd4;
937
937
C(cd) = cd5;
938
938
RETIRE_SUCCESS
939
939
}
@@ -1692,6 +1692,89 @@ function clause execute (CLoadTags(rd, cs1)) = {
1692
1692
}
1693
1693
}
1694
1694
1695
+ /*
1696
+ * Indirect sentries.
1697
+ *
1698
+ * At the risk of becoming CISC, the invocation instructions load, unseal, and
1699
+ * transfer control. They depend on helpers above for most of those tasks.
1700
+ */
1701
+
1702
+ union clause ast = CSealIPCC : (regidx, regidx)
1703
+ /*!
1704
+ * Capability register *cd* is replaced with capability register *cs1* and
1705
+ * sealed as an indirect, points-to-PCC sentry
1706
+ *
1707
+ * ## Exceptions
1708
+ *
1709
+ * An exception is raised if:
1710
+ * - *cs1*.**tag** is not set.
1711
+ * - *cs1* is sealed.
1712
+ * - *cs1*.**perms** does not grant both **Permit_Load** and
1713
+ * **Permit_Load_Capability**.
1714
+ */
1715
+ function clause execute (CSealIPCC(cd, cs1)) = {
1716
+ let cs1_val = C(cs1);
1717
+ if not (cs1_val.tag) then {
1718
+ handle_cheri_reg_exception(CapEx_TagViolation, cs1);
1719
+ RETIRE_FAIL
1720
+ } else if (isCapSealed(cs1_val)) then {
1721
+ handle_cheri_reg_exception(CapEx_SealViolation, cs1);
1722
+ RETIRE_FAIL
1723
+ } else if not (cs1_val.permit_load) then {
1724
+ handle_cheri_reg_exception(CapEx_PermitLoadViolation, cs1);
1725
+ RETIRE_FAIL
1726
+ } else if not (cs1_val.permit_load_cap) then {
1727
+ handle_cheri_reg_exception(CapEx_PermitLoadCapViolation, cs1);
1728
+ RETIRE_FAIL
1729
+ } else {
1730
+ C(cd) = sealCap(cs1_val, to_bits(cap_otype_width, otype_isentry_pcc));
1731
+ RETIRE_SUCCESS
1732
+ }
1733
+ }
1734
+
1735
+ union clause ast = CJALR_IPCC : (regidx, regidx)
1736
+ /*!
1737
+ * Jump through an indirect, points-to-PCC sentry capability held in
1738
+ * capability register cs, linking to cd.
1739
+ */
1740
+ function clause execute (CJALR_IPCC(cd, cs)) = {
1741
+ let cs_val = C(cs);
1742
+
1743
+ if not (cs_val.tag) then {
1744
+ handle_cheri_reg_exception(CapEx_TagViolation, cs);
1745
+ RETIRE_FAIL
1746
+ } else if not (isCapSealed(cs_val)) |
1747
+ signed(cs_val.otype) != otype_isentry_pcc then {
1748
+ handle_cheri_reg_exception(CapEx_SealViolation, cs);
1749
+ RETIRE_FAIL
1750
+ } else {
1751
+ let idc = unsealCap(cs_val);
1752
+ let idcaddr = cs_val.address;
1753
+
1754
+ if not (idc.permit_load) | not (idc.permit_load_cap) then {
1755
+ handle_cheri_reg_exception(CapEx_PermitLoadViolation, cs);
1756
+ RETIRE_FAIL
1757
+ } else if not(inCapBounds(idc, idcaddr, cap_size)) then {
1758
+ handle_cheri_reg_exception(CapEx_LengthViolation, cs);
1759
+ RETIRE_FAIL
1760
+ } else if not(is_aligned_addr(idcaddr, cap_size)) then {
1761
+ handle_mem_exception(idcaddr, E_Load_Addr_Align());
1762
+ RETIRE_FAIL
1763
+ } else {
1764
+ match load_cap_via_cap(0b0 @ cs, cs_val, idcaddr) {
1765
+ None() => RETIRE_FAIL,
1766
+ Some(v) => match cjalr_worker(cd, cs, v, zeros()) {
1767
+ RETIRE_FAIL => RETIRE_FAIL,
1768
+ RETIRE_SUCCESS => {
1769
+ C(31) = idc;
1770
+ RETIRE_SUCCESS
1771
+ }
1772
+ }
1773
+ }
1774
+ }
1775
+ }
1776
+ }
1777
+
1695
1778
/* avoid platform checks for reservation address misalignment */
1696
1779
function check_res_misaligned(vaddr : xlenbits, width : word_width) -> bool =
1697
1780
match width {
@@ -2419,6 +2502,9 @@ mapping clause encdec = JALR_PCC(rd, rs1) if (haveXcheri()) <-> 0b1111111 @ 0b
2419
2502
2420
2503
mapping clause encdec = CLoadTags(rd, cs1) if (haveXcheri()) <-> 0b1111111 @ 0b10010 @ cs1 @ 0b000 @ rd @ 0b1011011 if (haveXcheri())
2421
2504
2505
+ mapping clause encdec = CSealIPCC(cd, cs1) if (haveXcheri()) <-> 0b1111111 @ 0b11000 @ cs1 @ 0b000 @ cd @ 0b1011011 if (haveXcheri())
2506
+ mapping clause encdec = CJALR_IPCC(cd, cs1) if (haveXcheri()) <-> 0b1111111 @ 0b11001 @ cs1 @ 0b000 @ cd @ 0b1011011 if (haveXcheri())
2507
+
2422
2508
mapping clause encdec = CRRL(rd, rs1) if (haveXcheri()) <-> 0b1111111 @ 0b01000 @ rs1 @ 0b000 @ rd @ 0b1011011 if (haveXcheri())
2423
2509
mapping clause encdec = CRAM(rd, rs1) if (haveXcheri()) <-> 0b1111111 @ 0b01001 @ rs1 @ 0b000 @ rd @ 0b1011011 if (haveXcheri())
2424
2510
0 commit comments