@@ -786,13 +786,13 @@ def make_word(bs):
786
786
787
787
788
788
@cocotb .test ()
789
- async def test_virtual_read_illegal (dut ):
789
+ async def test_virtual_read (dut ):
790
790
"""
791
791
Tests CSR read(s) using the recovery protocol
792
792
"""
793
793
794
794
# Initialize
795
- i3c_controller , i3c_target , tb , recovery = await initialize (dut )
795
+ i3c_controller , i3c_target , tb , recovery = await initialize (dut , timeout = 500 )
796
796
797
797
# set regular device dynamic address
798
798
await i3c_controller .i3c_ccc_write (
@@ -803,21 +803,69 @@ async def test_virtual_read_illegal(dut):
803
803
ccc = CCC .DIRECT .SETDASA , directed_data = [(VIRT_STATIC_ADDR , [VIRT_DYNAMIC_ADDR << 1 ])]
804
804
)
805
805
806
- # Disable recovery mode
807
- status = 0x2 # "Recovery Mode"
808
- await tb .write_csr (
809
- tb .reg_map .I3C_EC .SECFWRECOVERYIF .DEVICE_STATUS_0 .base_addr , int2dword (status ), 4
810
- )
806
+ # Recovery commands to test
807
+ commands = [
808
+ ("Y" , "A" , I3cRecoveryInterface .Command .PROT_CAP ),
809
+ ("Y" , "A" , I3cRecoveryInterface .Command .DEVICE_ID ),
810
+ ("Y" , "A" , I3cRecoveryInterface .Command .DEVICE_STATUS ),
811
+ ("N" , "A" , I3cRecoveryInterface .Command .DEVICE_RESET ),
812
+ ("Y" , "A" , I3cRecoveryInterface .Command .RECOVERY_CTRL ),
813
+ ("N" , "A" , I3cRecoveryInterface .Command .RECOVERY_STATUS ),
814
+ ("N" , "R" , I3cRecoveryInterface .Command .HW_STATUS ),
815
+ ("N" , "R" , I3cRecoveryInterface .Command .INDIRECT_CTRL ),
816
+ ("N" , "R" , I3cRecoveryInterface .Command .INDIRECT_STATUS ),
817
+ ("N" , "R" , I3cRecoveryInterface .Command .INDIRECT_DATA ),
818
+ ("N" , "R" , I3cRecoveryInterface .Command .VENDOR ),
819
+ ("N" , "R" , I3cRecoveryInterface .Command .INDIRECT_FIFO_CTRL ),
820
+ ("N" , "R" , I3cRecoveryInterface .Command .INDIRECT_FIFO_STATUS ),
821
+ ("N" , "R" , I3cRecoveryInterface .Command .INDIRECT_FIFO_DATA ),
822
+ ]
811
823
812
- # Read the INDIRECT_FIFO_STATUS register
813
- data , pec_ok = await recovery .command_read (
814
- VIRT_DYNAMIC_ADDR , I3cRecoveryInterface .Command .INDIRECT_FIFO_STATUS
815
- )
824
+ result = True
825
+
826
+ # Test each command in recovery mode enabled and disabled. Recovery is
827
+ # initially enabled.
828
+ for recovery_mode in [True , False ]:
829
+ for req , scope , cmd in commands :
830
+
831
+ # Do the command
832
+ dut ._log .info (f"Command 0x{ cmd :02X} " )
833
+ data , pec_ok = await recovery .command_read (VIRT_DYNAMIC_ADDR , cmd )
834
+
835
+ is_nack = data == None and pec_ok == None
836
+ pec_ok = bool (pec_ok )
837
+
838
+ if is_nack :
839
+ dut ._log .info ("NACK" )
840
+ else :
841
+ dut ._log .info (f"ACK, pec_ok={ pec_ok } " )
842
+
843
+ # In recovery mode
844
+ if recovery_mode :
845
+ if is_nack :
846
+ dut ._log .error ("Scope R recovery command NACKed" )
847
+ result = False
848
+ # Not in recovery mode
849
+ else :
850
+ if scope == "A" and is_nack :
851
+ dut ._log .error ("Scope A recovery command NACKed" )
852
+ result = False
853
+ elif scope == "R" and not is_nack :
854
+ dut ._log .error ("Scope R recovery command ACKed" )
855
+ result = False
856
+
857
+ # Check PEC
858
+ if not is_nack and not pec_ok :
859
+ dut ._log .error ("PEC error!" )
860
+ result = False
861
+
862
+ # Disable recovery mode
863
+ status = 0x2 # "Recovery Mode"
864
+ await tb .write_csr (
865
+ tb .reg_map .I3C_EC .SECFWRECOVERYIF .DEVICE_STATUS_0 .base_addr , int2dword (status ), 4
866
+ )
816
867
817
- # Expect NACK
818
- # This is how cocotbext-i3c reports a NACK for a recovery command
819
- assert data == None
820
- assert pec_ok == None
868
+ assert result
821
869
822
870
# Wait
823
871
await Timer (1 , "us" )
0 commit comments