@@ -1032,6 +1032,8 @@ ot_otp_dj_lci_change_state_line(OtOTPDjState *s, OtOTPLCIState state, int line);
1032
1032
#define LCI_CHANGE_STATE (_s_ , _st_ ) \
1033
1033
ot_otp_dj_lci_change_state_line(_s_, _st_, __LINE__)
1034
1034
1035
+ #define OT_OTP_PART_DATA_OFFSET (_pix_ ) \
1036
+ ((unsigned)(OtOTPPartDescs[(_pix_)].offset))
1035
1037
#define OT_OTP_PART_DATA_BYTE_SIZE (_pix_ ) \
1036
1038
((unsigned)(OtOTPPartDescs[(_pix_)].size - \
1037
1039
sizeof(uint32_t) * NUM_DIGEST_WORDS))
@@ -1543,6 +1545,10 @@ static void ot_otp_dj_check_partition_integrity(OtOTPDjState *s, unsigned ix)
1543
1545
if (digest != pctrl -> buffer .digest ) {
1544
1546
trace_ot_otp_mismatch_digest (PART_NAME (ix ), ix , digest ,
1545
1547
pctrl -> buffer .digest );
1548
+
1549
+ TRACE_OTP ("%s: compute digest %016llx from %s\n" , __func__ , digest ,
1550
+ ot_otp_hexdump (pctrl -> buffer .data , part_size ));
1551
+
1546
1552
pctrl -> failed = true;
1547
1553
/* this is a fatal error */
1548
1554
ot_otp_dj_set_error (s , ix , OTP_CHECK_FAIL_ERROR );
@@ -1575,6 +1581,20 @@ static bool ot_otp_dj_is_backend_writable(OtOTPDjState *s)
1575
1581
return (s -> blk != NULL ) && blk_is_writable (s -> blk );
1576
1582
}
1577
1583
1584
+ static inline int ot_otp_dj_write_backend (OtOTPDjState * s , void * buffer ,
1585
+ unsigned offset , size_t size )
1586
+ {
1587
+ /*
1588
+ * the blk_pwrite API is awful, isolate it so that linter exceptions are
1589
+ * are not repeated over and over
1590
+ */
1591
+ // NOLINTBEGIN(clang-analyzer-optin.core.EnumCastOutOfRange)
1592
+ return blk_pwrite (s -> blk , (int64_t )(intptr_t )offset , (int64_t )size , buffer ,
1593
+ /* a bitfield of enum is not an enum item */
1594
+ (BdrvRequestFlags )0 );
1595
+ // NOLINTEND(clang-analyzer-optin.core.EnumCastOutOfRange)
1596
+ }
1597
+
1578
1598
static void ot_otp_dj_dai_init (OtOTPDjState * s )
1579
1599
{
1580
1600
DAI_CHANGE_STATE (s , OTP_DAI_IDLE );
@@ -1734,9 +1754,10 @@ static void ot_otp_dj_dai_write(OtOTPDjState *s)
1734
1754
}
1735
1755
1736
1756
unsigned waddr = address >> 2u ;
1737
-
1757
+ unsigned size ;
1738
1758
if (is_wide || is_digest ) {
1739
1759
waddr &= ~0b1u ;
1760
+ size = sizeof (uint64_t );
1740
1761
1741
1762
uint32_t dst_lo = s -> otp -> data [waddr ];
1742
1763
uint32_t dst_hi = s -> otp -> data [waddr + 1u ];
@@ -1747,29 +1768,38 @@ static void ot_otp_dj_dai_write(OtOTPDjState *s)
1747
1768
if ((dst_lo & ~lo ) || (dst_hi & ~hi )) {
1748
1769
qemu_log_mask (LOG_GUEST_ERROR , "%s: Cannot clear OTP bits\n" ,
1749
1770
__func__ );
1750
- ot_otp_dj_dai_set_error (s , OTP_MACRO_WRITE_BLANK_ERROR );
1751
- return ;
1771
+ ot_otp_dj_set_error (s , OTP_ENTRY_DAI , OTP_MACRO_WRITE_BLANK_ERROR );
1752
1772
}
1753
1773
1754
1774
s -> otp -> data [waddr ] = lo ;
1755
1775
s -> otp -> data [waddr + 1u ] = hi ;
1756
1776
} else {
1777
+ size = sizeof (uint32_t );
1778
+
1757
1779
uint32_t dst = s -> otp -> data [waddr ];
1758
1780
uint32_t data = s -> regs [R_DIRECT_ACCESS_WDATA_0 ];
1759
1781
1760
1782
if (dst & ~data ) {
1761
1783
qemu_log_mask (LOG_GUEST_ERROR , "%s: Cannot clear OTP bits\n" ,
1762
1784
__func__ );
1763
- ot_otp_dj_dai_set_error (s , OTP_MACRO_WRITE_BLANK_ERROR );
1764
- return ;
1785
+ ot_otp_dj_set_error (s , OTP_ENTRY_DAI , OTP_MACRO_WRITE_BLANK_ERROR );
1765
1786
}
1766
1787
1767
1788
s -> otp -> data [waddr ] = data ;
1768
1789
}
1769
1790
1770
- /* fake slow access to OTP cell */
1791
+ uintptr_t offset = (uintptr_t )s -> otp -> data - (uintptr_t )s -> otp -> storage ;
1792
+ if (ot_otp_dj_write_backend (s , & s -> otp -> data [waddr ],
1793
+ (unsigned )(offset + waddr * sizeof (uint32_t )),
1794
+ size )) {
1795
+ error_report ("%s: cannot update OTP backend" , __func__ );
1796
+ ot_otp_dj_dai_set_error (s , OTP_MACRO_ERROR );
1797
+ return ;
1798
+ }
1799
+
1771
1800
DAI_CHANGE_STATE (s , OTP_DAI_WRITE_WAIT );
1772
1801
1802
+ /* fake slow access to OTP cell */
1773
1803
timer_mod (s -> dai -> delay ,
1774
1804
qemu_clock_get_ns (OT_VIRTUAL_CLOCK ) + DAI_WRITE_DELAY_NS );
1775
1805
}
@@ -1839,7 +1869,14 @@ static void ot_otp_dj_dai_digest(OtOTPDjState *s)
1839
1869
1840
1870
DAI_CHANGE_STATE (s , OTP_DAI_DIG_READ );
1841
1871
1842
- const uint8_t * data = (const uint8_t * )pctrl -> buffer .data ;
1872
+ const uint8_t * data ;
1873
+
1874
+ if (OtOTPPartDescs [partition ].buffered ) {
1875
+ data = ((const uint8_t * )s -> otp -> data ) +
1876
+ OT_OTP_PART_DATA_OFFSET (partition );
1877
+ } else {
1878
+ data = (const uint8_t * )pctrl -> buffer .data ;
1879
+ }
1843
1880
unsigned part_size = OT_OTP_PART_DATA_BYTE_SIZE (partition );
1844
1881
1845
1882
DAI_CHANGE_STATE (s , OTP_DAI_DIG );
@@ -1848,6 +1885,9 @@ static void ot_otp_dj_dai_digest(OtOTPDjState *s)
1848
1885
ot_otp_dj_compute_partition_digest (s , data , part_size );
1849
1886
s -> dai -> partition = partition ;
1850
1887
1888
+ TRACE_OTP ("%s: next digest %016llx from %s\n" , __func__ ,
1889
+ pctrl -> buffer .next_digest , ot_otp_hexdump (data , part_size ));
1890
+
1851
1891
DAI_CHANGE_STATE (s , OTP_DAI_DIG_WAIT );
1852
1892
1853
1893
/* fake slow access to OTP cell */
@@ -1865,29 +1905,31 @@ static void ot_otp_dj_dai_write_digest(void *opaque)
1865
1905
1866
1906
OtOTPPartController * pctrl = & s -> partctrls [s -> dai -> partition ];
1867
1907
unsigned address = OtOTPPartDescs [s -> dai -> partition ].digest_offset ;
1868
- address >>= 3u ;
1869
- uint64_t * dst = & ((uint64_t * )s -> otp -> data )[address ];
1908
+ unsigned dwaddr = address / sizeof ( uint64_t ) ;
1909
+ uint64_t * dst = & ((uint64_t * )s -> otp -> data )[dwaddr ];
1870
1910
uint64_t data = pctrl -> buffer .next_digest ;
1871
1911
pctrl -> buffer .next_digest = 0 ;
1872
- OtOTPError error ;
1912
+
1873
1913
if (* dst & ~data ) {
1874
1914
qemu_log_mask (LOG_GUEST_ERROR , "%s: Cannot clear OTP bits\n" , __func__ );
1875
- error = OTP_MACRO_WRITE_BLANK_ERROR ;
1915
+ ot_otp_dj_set_error ( s , OTP_ENTRY_DAI , OTP_MACRO_WRITE_BLANK_ERROR ) ;
1876
1916
} else {
1877
1917
* dst |= data ;
1878
- error = OTP_NO_ERROR ;
1879
1918
}
1880
1919
1881
- if (error == OTP_NO_ERROR ) {
1882
- /* fake slow access to OTP cell */
1883
- DAI_CHANGE_STATE (s , OTP_DAI_WRITE_WAIT );
1884
-
1885
- timer_mod (s -> dai -> delay ,
1886
- qemu_clock_get_ns (OT_VIRTUAL_CLOCK ) + DAI_WRITE_DELAY_NS );
1887
- } else {
1888
- /* TODO: no idea on how to report the error since partition is undef */
1889
- ot_otp_dj_dai_set_error (s , error );
1920
+ uintptr_t offset = (uintptr_t )s -> otp -> data - (uintptr_t )s -> otp -> storage ;
1921
+ if (ot_otp_dj_write_backend (s , dst , (unsigned )(offset + address ),
1922
+ sizeof (uint64_t ))) {
1923
+ error_report ("%s: cannot update OTP backend" , __func__ );
1924
+ ot_otp_dj_dai_set_error (s , OTP_MACRO_ERROR );
1925
+ return ;
1890
1926
}
1927
+
1928
+ DAI_CHANGE_STATE (s , OTP_DAI_WRITE_WAIT );
1929
+
1930
+ /* fake slow access to OTP cell */
1931
+ timer_mod (s -> dai -> delay ,
1932
+ qemu_clock_get_ns (OT_VIRTUAL_CLOCK ) + DAI_WRITE_DELAY_NS );
1891
1933
}
1892
1934
1893
1935
static void ot_otp_dj_dai_complete (void * opaque )
@@ -3029,11 +3071,9 @@ static void ot_otp_dj_lci_write_complete(OtOTPDjState *s, bool success)
3029
3071
const OtOTPPartDesc * lcdesc = & OtOTPPartDescs [OTP_PART_LIFE_CYCLE ];
3030
3072
unsigned lc_data_off = lcdesc -> offset / sizeof (uint32_t );
3031
3073
uintptr_t offset = (uintptr_t )s -> otp -> data - (uintptr_t )s -> otp -> storage ;
3032
- // NOLINTBEGIN(clang-analyzer-optin.core.EnumCastOutOfRange)
3033
- if (blk_pwrite (s -> blk , (int64_t )(intptr_t )(offset + lcdesc -> offset ),
3034
- lcdesc -> size , & s -> otp -> data [lc_data_off ],
3035
- (BdrvRequestFlags )0 )) {
3036
- // NOLINTEND(clang-analyzer-optin.core.EnumCastOutOfRange)
3074
+ if (ot_otp_dj_write_backend (s , & s -> otp -> data [lc_data_off ],
3075
+ (unsigned )(offset + lcdesc -> offset ),
3076
+ lcdesc -> size )) {
3037
3077
error_report ("%s: cannot update OTP backend" , __func__ );
3038
3078
if (lci -> error == OTP_NO_ERROR ) {
3039
3079
lci -> error = OTP_MACRO_ERROR ;
0 commit comments