Skip to content

Commit 7fb52c7

Browse files
wkkunakgugala
authored andcommitted
ver: recovery: Add OCP register access test
Signed-off-by: Wiktoria Kuna <[email protected]>
1 parent 352d1e0 commit 7fb52c7

File tree

1 file changed

+96
-1
lines changed

1 file changed

+96
-1
lines changed

verification/cocotb/top/lib_i3c_top/test_recovery.py

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import random
55

66
from boot import boot_init
7-
from bus2csr import bytes2int, dword2int, int2bytes, int2dword
7+
from bus2csr import bytes2int, compare_values, dword2int, int2bytes, int2dword
88
from ccc import CCC
99
from cocotbext_i3c.i3c_controller import I3cController
1010
from cocotbext_i3c.i3c_recovery_interface import I3cRecoveryInterface
@@ -1419,3 +1419,98 @@ async def dev_agent(buffer):
14191419

14201420
# Check
14211421
assert image_words == xferd_words
1422+
1423+
1424+
def csr_access_test_data(tb):
1425+
test_data = []
1426+
for reg_name in tb.reg_map.I3C_EC.SECFWRECOVERYIF:
1427+
if reg_name in ["start_addr", "INDIRECT_FIFO_DATA", "DEVICE_RESET"]:
1428+
continue
1429+
reg = getattr(tb.reg_map.I3C_EC.SECFWRECOVERYIF, reg_name)
1430+
addr = reg.base_addr
1431+
wdata = random.randint(0, 2**32 - 1)
1432+
exp_rd = 0
1433+
for f_name in reg:
1434+
if f_name in ["base_addr", "offset"]:
1435+
continue
1436+
f = getattr(reg, f_name)
1437+
if f.sw == "r":
1438+
data = (f.reset << f.low) & f.mask
1439+
elif f.woclr or f.hwclr:
1440+
data = 0
1441+
if wdata % 2:
1442+
data = (f.reset << f.low) & f.mask
1443+
else:
1444+
data = wdata & f.mask
1445+
# The reset value of 'INDIRECT_FIFO_STATUS_3' is 0 but it's set
1446+
# by 'recovery_executor' to 'IndirectFifoDepth' parameter
1447+
if reg_name == "INDIRECT_FIFO_STATUS_3" and f_name == "FIFO_SIZE":
1448+
data = 0x40
1449+
# The reset value of 'INDIRECT_FIFO_STATUS_4' is currently unused
1450+
# and tied to 0
1451+
if reg_name == "INDIRECT_FIFO_STATUS_4" and f_name == "MAX_TRANSFER_SIZE":
1452+
data = 0x0
1453+
1454+
exp_rd |= data
1455+
test_data.append([reg_name, addr, wdata, exp_rd])
1456+
return test_data
1457+
1458+
1459+
@cocotb.test()
1460+
async def test_ocp_csr_access(dut):
1461+
# Perform the recovery protocol to obtain access to CSRs
1462+
i3c_controller, _, tb, recovery = await initialize(dut)
1463+
1464+
# set regular device dynamic address
1465+
await i3c_controller.i3c_ccc_write(
1466+
ccc=CCC.DIRECT.SETDASA, directed_data=[(STATIC_ADDR, [DYNAMIC_ADDR << 1])]
1467+
)
1468+
# set virtual device dynamic address
1469+
await i3c_controller.i3c_ccc_write(
1470+
ccc=CCC.DIRECT.SETDASA, directed_data=[(VIRT_STATIC_ADDR, [VIRT_DYNAMIC_ADDR << 1])]
1471+
)
1472+
1473+
# Write to the RESET CSR (one word)
1474+
b0, b1, b2, b3 = [random.randint(0, 255) for _ in range(4)]
1475+
await recovery.command_write(
1476+
VIRT_DYNAMIC_ADDR, I3cRecoveryInterface.Command.DEVICE_RESET, [b3, b2, b1, b0]
1477+
)
1478+
1479+
# Wait & read the CSR from the AHB/AXI side
1480+
await Timer(1, "us")
1481+
1482+
status = dword2int(await tb.read_csr(tb.reg_map.I3C_EC.SECFWRECOVERYIF.DEVICE_STATUS_0.base_addr, 4))
1483+
data = dword2int(await tb.read_csr(tb.reg_map.I3C_EC.SECFWRECOVERYIF.DEVICE_RESET.base_addr, 4))
1484+
1485+
# Check
1486+
protocol_status = (status >> 8) & 0xFF
1487+
assert protocol_status == 0
1488+
assert data == b1 << 16 | b2 << 8 | b3
1489+
1490+
reg_test_data = csr_access_test_data(tb)
1491+
1492+
for name, addr, wdata, exp_rd in reg_test_data:
1493+
if name == "INDIRECT_FIFO_CTRL_0":
1494+
exp_rd &= 0xFFFF00FF # 2nd byte is W1C
1495+
elif name == "RECOVERY_CTRL":
1496+
exp_rd &= 0xFF00FFFF # 3rd byte is W1C
1497+
elif name == "DEVICE_STATUS_0":
1498+
recovery_status = wdata
1499+
exp_recovery_status = exp_rd
1500+
continue # Do not disable recovery mode
1501+
1502+
await tb.write_csr(addr, int2dword(wdata), 4)
1503+
# Ensure the data is committed before making a read access
1504+
await RisingEdge(tb.clk)
1505+
rd_data = await tb.read_csr(addr)
1506+
compare_values(int2dword(exp_rd), rd_data, addr)
1507+
1508+
# DEVICE_STATUS_0 CSR was skipped in previous iteration as it can disable the
1509+
# recovery mode necessary for other CSRs
1510+
recovery_status_addr = tb.reg_map.I3C_EC.SECFWRECOVERYIF.DEVICE_STATUS_0.base_addr
1511+
await tb.write_csr(
1512+
tb.reg_map.I3C_EC.SECFWRECOVERYIF.DEVICE_STATUS_0.base_addr, int2dword(recovery_status), 4
1513+
)
1514+
1515+
rd_data = await tb.read_csr(recovery_status_addr)
1516+
compare_values(int2dword(exp_recovery_status), rd_data, recovery_status_addr)

0 commit comments

Comments
 (0)