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