;

연암과 다산 사이

블로그 이미지
문패 달고 보니까 넘 커다란 이름이네요 ^^; 행여 고래 등 사이에 끼인 새우가 되지 않기를 ㅎㅎ 연암은 고미숙님의 '열하일기, 웃음과 역설의 유쾌한 시공간'에서, 다산은 '다산연구소' (http://www.edasan.org)에서 삘 받았슴다. 잼난 놀이터가 되었으면... ^^
by 명랑만화
  • Total hit
  • Today hit
  • Yesterday hit
11-28 10:17

%% LeCroy Exerciser Script - For NVMe Emulation
* Reference : PETrainerScriptManual_v*.pdf
http://teledynelecroy.com/protocolanalyzer/pci-express/summit-z3-16-exerciser-with-smbus-support

 

* LeCroy Exerciser Script
http://ya-n-ds.tistory.com/3108 : PCIe Commands
http://ya-n-ds.tistory.com/3116 : NVMe (1) Preparation for IO
http://ya-n-ds.tistory.com/3131 : NVMe (2) IO Command ( + MCTP, Completion options )

 

 

< Step 0. Option Preparation for NVMe Host Emulation >
# Exerciser BAR Menu : Setup -> Generation Options -> Transactions
- Host Memory Regions : Mem_64, Address 0x4_2FAA_8000, Length 0x1_0000 ( 4KB Blocks )


< Step 1. Configuration for NVMe >
Config=Definitions
{
    HOST_REQUESTER_ID                  = (1:0:0)
    DEVICE_ID                          = (2:1:0)

 

    BAR0_ADDRESS = 0xEC03_0000  ;; Little Endian
    BAR0_ADDRESS_BIG_END = 0x0000_003EC

 

    BAR2_ADDRESS_BIG_END = 0x0000_002EC ;; Little Endian = 0xEC02_0000

 

    PXCAP_BASE_ADDR = 0x0000_0070 ;; PCIe Capability Base Address ( Device HW dependency )
    PXCAP_PXDC_OFFSET = 0x0000_0008 ;; PCIe Device Congrol register offset

 

    MSI_X_TABLE_OFFSET = 0x0000_4000  ;; Device HW dependency, This can be read from MSIXCP.MTAB register
    MSI_X_TABLE_BASE_ADDR = ( BAR0_ADDRESS + MSI_X_TABLE_OFFSET )

 

    MSI_X_CAP_BASE_ADDR = 0xB0  ;; Device HW dependency

 

    HOST_MSIX_INTR0_BASE_ADDR_BIG_END = 0x0000_E0FE  ;; MSI-X Interrupt0 BA in Host - for Admin CQ
    HOST_MSIX_INTR0_BASE_ADDR = 0xFEE0_0000  ;; Littel Endian
    HOST_MSIX_INTR1_BASE_ADDR_BIG_END = 0x0000_E2FE  ;; MSI-X Interrupt1 BA in Host - for IO CQ
    HOST_MSIX_INTR1_BASE_ADDR = 0xFEE2_0000  ;; Littel Endian

 

    HOST_MSIX_INTR0_MSG_DATA_BIG_END = 0xB040_0000  ;; MSI-X Interrupt0 Message Data, Littel Endian = 0x0000_40B0
    HOST_MSIX_INTR1_MSG_DATA_BIG_END = 0xA040_0000  ;; MSI-X Interrupt1 Message Data, Littel Endian = 0x0000_40A0

 

    CONTROLLER_REGISTERS_BASE          = BAR0_ADDRESS

 

    IO_QUEUE_SIZE = 0xFF  ;; Device dependency

 

    IO_SQ_NUM_PAYLOAD = 0x01000000  ;; 0x0000_0001
    ;IO_SQ_NUM_PAYLOAD = 0x02000000  ;; 0x0000_0002

 

    COUNT_REPEAT = 4 ;; Count is from 0 to 'N-1'

 

    TO_FOR_WAIT = 100000 ; SQ Tail Doorbell -> 33us -> [R<-] MRd -> 190us -> CplD
    MRd_TAG_NUM = 0

 

    IO_DB_NUM = 0x00000001  ;; IO Door Bell Number #1
    IO_DB_NUM_BIG_END = ( IO_DB_NUM << 24 )
}

 

template = TLP
{
    Name = "Temp_ConfigWrite0"
   
    TLPType=CfgWr0
    Length = 1
    RequesterId = HOST_REQUESTER_ID
    FirstDwBe = 0xF
    DeviceId = DEVICE_ID
}

 

template = TLP
{
    Name = "Temp_ConfigRead0"
   
    TLPType=CfgRd0
    Length = 1
    RequesterId = HOST_REQUESTER_ID
    FirstDwBe = 0xF
    DeviceId = DEVICE_ID
}

 

template = TLP
{
    Name = "Temp_MWr32_OneDword"
   
    TLPType = MWr32
    Length = 1
    RequesterId = HOST_REQUESTER_ID
    FirstDwBe = 0xF
}

 

template = TLP
{
    Name = "Temp_MRd32_OneDword"
   
    TLPType = MRd32
    Length = 1
    RequesterId = HOST_REQUESTER_ID
    FirstDwBe = 0xF
}

 

;; PCIe VDM Header
; Test for Payload size(Length), Packet number,  Message Tag
template = TLP
{
    Name = "Temp_PCIe_VDM_Header"
    PSN = Incr
   
    ;; ** PCIe Medium-Specifice Header
    ;; 1st Dword ( Byte0~3 )
    TLPType=MsgD   ; Fmt[6:5]=11b(4DW Header with Data) + Type[4:3]=10b(Message)
    ;MessageRoute = ByID  ; Type[2:0] ( ByID = 010b = 0x2 )
    MessageRoute = 0x2
    Length = 2    ; Payload size = 2 Dword for Set EID
   
    ;; 2nd Dword ( Byte4~7 )
    RequesterID = (1:0:0)
    Tag = 0x00     ; Rsvd[7:6] + PadLen[5:4] + MCTP VDM Code(0000b)
                   ; PadLen = 0 for Aligned Payload
    MessageCode = Vendor_Defined_Type1  ; Should be VDM type 1 for MCTP packets = 0x7F
   
    ;; 3rd DWord ( Byte8~11 )
    DeviceID = (2:0:0)   ; Byte8,9
    VendorId = 0x1AB4    ; Byte10,11 - DMTF Vendor ID
   
    ;; 4th Dword ( Byte12~15 : MCTP Transport Header )
    ;VendorData = 0x0108F0C8 ; Big Endian -  Packet Seq #[5:4] = 00b, TO[3]=0, Message Tag[2:0]=0x0
    VendorData = 0x0108F0EB ; Big Endian - Packet Seq # = 10b, TO=1, Message Tag=0x3   
    ;Byte12 bit[3:0]=Header Version=1  /  Byte13=Destination EID=0x08  /  Byte14=Source EID=0xF0
    ;   cf. Byte13 - Destination EID : 0=Null EID, 1~7=Reserved for Future definition, 0xFF=Broadcast EID
    ;Byte15 : bit[7]=SOM , bit[6]=EOM are set to 1, bit[5:4]=Pkt # =0
    ;Byte15 : bit[3]=TO(Tag Owner) =1(=Requester)  /  bit[2:0]=Msg Tag
   
    ;;** PCIe VDM Data = MCTP Packet Payload ( Message body )
    ;1st Dword
    ;   Byte1=Message Type('MCTP Control'=000_0000b),
    ;   Byte2 - bit[7]=Rq('1'=Request), bit[6]=D(Datagram=0), bit[4:0]=Instance ID
    ;   Byte3 - Command Code=0x01(=Set EID)
    ;   Byte4 - bit[1:0] MCTP_CMD_SETID_Operation
    ;               ( 00b=Set ID, 01b=Force ID, 10b=Reset EID, 11b=Set Discovered Flag )
    ;2nd Dword
    ;   Byte1 - MCTP_CMD_SEID_EPID= 0x09  /  Byte2~4 - PAD=0x0 ( determined by 'Pad Len' )
    ;Payload = (0x00800100 0x09000000)
}

 

 

< Step 4-1. NVMe IO Command - Write >
;; Pre-program command in the Host Memory Region. This is the Mem_64 Host region
;; defined in the generation options file "nvme_host_gen_options.gen"
Structure=NVMe
{
    Location = Mem64
    Offset = 0x10000
    NVMeStructType=NVMCommand
    OpcodeNvm = Write
    CID = 0
    NamespaceId = 1
    PRP1_Low = 0x2FB08000
    PRP1_High = 0x4
    ;PRP2_Low = 0x2FB18000
    ;PRP2_High = 0x4
    NumLBlocks = 0 ; 1 -> 0 ( Zero base value : 0=4KB ) - Only PRP1 is reqired
    ;NumLBlocks = 1 ; For 4KB block size, PRP2 is necessary
}

 

;; Write Queue 1 SQ Tail Doorbell
packet="Temp_MWr32_OneDword"
{
    Tag = 0
    Address = ( CONTROLLER_REGISTERS_BASE + 0x1008 )

    ;Payload = ( 0x01000000 )  ;; 0x0000_0001
    Payload = IO_SQ_NUM_PAYLOAD
}

 

;; Wait for the Controller to process the command.
;; The last thing would be the MSI-X interrupt at vector 1
;; Normally Host driver matches MSI-X vector # and Submission Queue #
wait=TLP
{
    TLPType = MWr32
    Address = HOST_MSIX_INTR1_BASE_ADDR
}

 

;; Write Queue 1 Completion Queue Head Doorbell
packet="Temp_MWr32_OneDword"
{
    Tag = 1
    Address = ( CONTROLLER_REGISTERS_BASE + 0x100C )

    ;Payload = ( 0x01000000 )  ;; 0x0000_0001
    Payload = IO_SQ_NUM_PAYLOAD
}

 

 

< Step 4-2. NVMe IO Command - Read >
;; Pre-program command in the Host Memory Region. This is the Mem_64 Host region
Structure=NVMe
{
    Location = Mem64
    Offset = 0x10000
    NVMeStructType=NVMCommand
    OpcodeNvm = Read
    CID = 0
    NamespaceId = 1
    PRP1_Low = 0x3F246000
    PRP1_High = 0x8
    NumLBlocks = 1
}


;; Write Queue 1 SQ Tail Doorbell
packet="Temp_MWr32_OneDword"
{
    Tag = 0
    Address = ( CONTROLLER_REGISTERS_BASE + 0x1008 )
    Payload = IO_SQ_NUM_PAYLOAD
}

 

;; Wait for the Controller to process the command.
;; The last thing would be the MSI-X interrupt at vector 1
;; Normally Host driver matches MSI-X vector # and Submission Queue #
wait=TLP
{
    TLPType = MWr32
    Address = CQ1_INT_VECTOR_ADDRESS
}

 

;; Write Queue 1 Completion Queue Head
packet="Temp_MWr32_OneDword"
{
    Tag = 1
    Address = ( CONTROLLER_REGISTERS_BASE + 0x100C )
    Payload = IO_SQ_NUM_PAYLOAD
}


 

< Step 4-3. NVMe IO Command - Write + MCTP >
Repeat = Begin { Count = (COUNT_REPEAT&IO_QUEUE_SIZE) Counter=qq }

 

;; Pre-program command in the Host Memory Region. This is the Mem_64 Host region
;; defined in the generation options file "nvme_host_gen_options.gen"
AddressSpace=Write
{
    Location = Mem64  ;; 0x4_2FAA_8000 ( defined in Exerciser Generation Options : Host Memory region of Transactions menu )
    Offset = 0x60000  ;; for 0x4_2FB0_8000 ( PRP1 for Write command )
    Size = 0x1000  ;; 4KB
    LoadFrom = Incr
}

 

AddressSpace=Write
{
    Location = Mem64  ;; 0x4_2FAA_8000
    Offset = 0x61000  ;; for 0x4_2FB1_8000 ( PRP1 for Write command )
    Size = 0x1000  ;; 4KB
    LoadFrom = Ones
}


Structure=NVMe
{
    Location = Mem64
    ;Offset = 0x10000
    Offset = ( 0x10000  + qq*0x40 )  ;; Stride : 16DW=64Byte

 

    NVMeStructType=NVMCommand
    OpcodeNvm = Write

 

    ;CID = 0
     CID = ( IO_QUEUE_SIZE & qq )

 

     NamespaceId = 1  ; Port0
    ;NamespaceId = 2  ; Port1

 

    ;PRP1_Low = 0x2FB08000
    PRP1_Low = ( 0x2FB08000 + ((0x1&qq)<<12) )  ;; Based on 'AddressSpace=Write'
    PRP1_High = 0x4

    NumLBlocks = 0 ; 1 -> 0 ( Zero base value : 0=4KB ) - Only PRP1 is reqired
    ;NumLBlocks = 1 ; For > 4KB block size, PRP2 is necessary
}

 

;; Write Queue 1 SQ Tail Doorbell
packet="Temp_MWr32_OneDword"
{
    ;Tag = 0
    Tag = (0 + qq*0x2)

    Address = ( CONTROLLER_REGISTERS_BASE + 0x1008 )

    ;Payload = IO_SQ_NUM_PAYLOAD
    Payload = ( [(1 + (qq&IO_QUEUE_SIZE))<<24 ] )  ;; Increase by 1 based on 'qq'
}

 

;; Wait for the Controller to process the command.
;; The last thing would be the MSI-X interrupt at vector 1
;; Normally Host driver matches MSI-X vector # and Submission Queue #
wait=TLP
{
    TLPType = MWr32
    Address = HOST_MSIX_INTR1_BASE_ADDR
}


;; Write Queue 1 Completion Queue Head
packet="Temp_MWr32_OneDword"
{
    ;Tag = 1
    Tag = (1 + qq*0x2)

    Address = ( CONTROLLER_REGISTERS_BASE + 0x100C )
    ;Payload = IO_SQ_NUM_PAYLOAD
    Payload = ( [(1 + (qq&IO_QUEUE_SIZE))<<24 ] )
}

 

;; MCTP over PCIe VDM Command
Loop = Begin { count = COUNT_LOOP }
Packet="Temp_PCIe_VDM_Header"
{
    ;2nd Dword
    ;   Byte1 - MCTP_CMD_SEID_EPID= 0x09  /  Byte2~4 - PAD=0x0 ( determined by 'Pad Len' )
    RequesterID = HOST_REQUESTER_ID  ;; Added for Previous NVMe setting
   
    ;; 3rd DWord ( Byte8~11 )
    DeviceID = DEVICE_ID ; Byte8,9

    ;; ** PCIe Medium-Specifice Header
    ;; 1st Dword ( Byte0~3 )
    Length = 16 ; 64B

    ;; 2nd Dword ( Byte4~7 )
    Tag = 0x00    ; Rsvd[7:6] + PadLen[5:4] + MCTP VDM Code(0000b)
        ; PadLen = 0 for Aligned Payload
    ;; ** Payload
    Payload = Incr
}

 

wait=DLLP
{    DLLPType = Ack   }

Loop = End

Repeat =End

 


< Step 4-4. NVMe IO Command for Completion with CA or UR >
;; CA(Completer Abort), UR(Unsupported Request)
Structure=NVMe
{
    Location = Mem64
   
    ;Offset = 0x10000
    Offset = ( 0x10000 + 0x40*(IO_DB_NUM_LITTLE_END - 1) ) ;; Co-relation to IO Doorbell Number
   
    NVMeStructType=NVMCommand
    OpcodeNvm = Write
    CID = 0
    NamespaceId = 1
    PRP1_Low = 0x2FB08000
    PRP1_High = 0x4
    ;PRP2_Low = 0x2FB18000
    ;PRP2_High = 0x4
    NumLBlocks = 0 ; 1 -> 0 ( Zero base value : 0=4KB ) - Only PRP1 is reqired
    ;NumLBlocks = 1 ; For > 4KB block size, PRP2 is necessary
}

 

;; Write Queue 1 SQ Tail Doorbell
packet="Temp_MWr32_OneDword"
{
    Tag = 0
    Address = ( CONTROLLER_REGISTERS_BASE + 0x1008 )
    Payload = IO_DB_NUM_BIG_END
}

 

;; For CA Completion in response to MRd from Device
; Wait for MRd TLP from Device or for Timeout for Next step
Wait=TLP
{
    TLPType=MRd64
    Tag = MRd_TAG_NUM  ;; Check the Tag Number
    Timeout = TO_FOR_WAIT  ;; [ns] If the TLP is not received, then the execution contienues after timeout expires
}

;; Cpl packet sent late

;; For Host to Send Completion with CA or UR to Device
Packet=TLP
{
    TLPType = CplD
    TD = 0   
    ;Length = 32  ;; Based on the Request from Device
    Length = 16
   
    Tag = MRd_TAG_NUM
    ComplStatus = CA  ;; Completer Abort
    ;ComplStatus = UR  ;; Unsuppoted Request
   
    ;ByteCount = 128
    ByteCount = 64
   
    Payload = Ones
    RequesterId = DEVICE_ID
}

 

;; Wait for the Controller to process the command.
wait=TLP
{
    TLPType = MWr32
    Address = HOST_MSIX_INTR1_BASE_ADDR
}

; Write Queue 1 Completion Queue Head Doorbell
packet="Temp_OneDwordWrite"
{
    Tag = 1
    Address = ( CONTROLLER_REGISTERS_BASE + 0x100C )
    Payload = IO_DB_NUM_BIG_END
}

AND

ARTICLE CATEGORY

분류 전체보기 (4415)
올드Boy다이어리 (530)
올드Boy@Jeju (83)
올드Boy@Road (131)
올드Boy@Book (58)
숨은길찾기 (14)
스펙트럼 (104)
우물밖엿보기 (32)
교회에말걸기 (226)
이어지는글들 (52)
하하호호히히 (73)
어?...아하! (124)
대한늬우스 (1640)
세계는지금 (264)
차한잔의여유 (64)
La Vita E Bella (230)
좋은나라만들기 (91)
트위터세상 (67)
사람&말 (609)
호모파베르 (20)

RECENT ARTICLE

RECENT COMMENT

RECENT TRACKBACK

CALENDAR

«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

ARCHIVE