This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320C6678: 64-bit PCIe Addressing Boot Problem

Part Number: TMS320C6678

I am working on booting a C6678 in PCIe 64-bit addressing mode.  The DEVSTAT register is configred as:

PACLKSEL:        0b0
PCIESSEN:        0b1    (PCIe enabled)
PCIESSMODE[1:0]: 0b00   (PCIe endpoint)
BOOTMODE[12:0]:  0x11E4 (BARs 2 and 4 are 2GB, PCIe boot mode)
LENDIAN:         0b1    (little endian)


As expected BAR0 is 4KB while BARs 2 and 4 are configured for 2GB apertures. I am able to access various registers and memory on the DSP and have ported the linux PCIe bootloader example to Windows OS and adapted it to work with 64-bit (instead of 32-bit) BARs.  

Using Blackhawk debugger, I have confirmed that I am writing code to L2SRAM for core0 and am also writing the MAGIC_ADDR at 0x0087FFFC.  I have tried issuing legacy interrupts as well as MSI interrupts to wake the ROM bootloader but PC seems to be sitting at an IDLE instruction at 0x20b01290:

# disassembly
20b01290: 0001E000 IDLE
20b01294: 0187E828 MVK.S1 0x0fd0,A3
20b01298: 01905868 MVKH.S1 0x20b00000,A3
20b0129c: E1200001 .fphead n, l, W, BU, nobr, nosat, 0001001b
20b012a0: 02181FDA MV.L2X A6,B4
20b012a4: 000C1362 B.S2X A3
20b012a8: 0200A358 MVK.L1 0,A4
20b012ac: 01846162 ADDKPC.S2 0x20b012b0,B3,3
20b012b0: 000403E2 MVC.S2 CSR,B0
20b012b4: 000000CA CLR.S2 B0,0,0,B0
20b012b8: 008003A2 MVC.S2 B0,CSR
20b012bc: 00000000 NOP
20b012c0: 029403A2 MVC.S2 B5,ISTP
20b012c4: 053C22E4 LDW.D2T1 *+B15[1],A10
20b012c8: 71F7 LDW.D2T2 *++B15[2],B3
20b012ca: 6C6E NOP 4
20b012cc: 008CA362 BNOP.S2 B3,5
20b012d0: 01BC54F6 STW.D2T2 B3,*B15--[2]
20b012d4: 026E1A2A MVK.S2 0xffffdc34,B4
20b012d8: 0210586A MVKH.S2 0x20b00000,B4
20b012dc: E0800000 .fphead n, l, W, BU, nobr, nosat, 0000100b
20b012e0: 00100362 B.S2 B4
20b012e4: 026EA028 MVK.S1 0xffffdd40,A4

The boot log is:

0x00873200   00000000 0000000A 00000001 5CA8ADFE 95BF81F1 43C5BB6F DDC4C431 DCDD7559
0x00873220   78EDFFEF EFF8BF7D 7975FBD5 B68DA98E 66CEC969 E9FBA8AC 7DDFD56C C5AB3342
0x00873240   DE7D985F 7317D62B 9CB2F7C0 297AF3FF 20755B7F 5D572A7B DF2DC98A DBB2EAC7
0x00873260   AEEAF646 8CA128F9 DF3EEFB8 1AEC9D9F 7277AC53 EE4F9A0F 52EFD435 5F833A79
0x00873280   2A3C6843 C982ACC4 11600A71 04AA8362 F2654E44 09457462 0117D4A0 F21F5A0C
0x008732A0   B52260D4 21358D09 784D965A 0062DE26 94900A81 094065D1 33B34162 E15CB645
0x008732C0   C3241CA2 3A011A7A 20814804 76195CE0 067049C1 93D10A2A 6B06B0E9 967B6C85

The Boot Progress register stack is:

0x008732E0   00000001 00000004 0000000A 67EA5572 C53DF566 055EB6CD 04370E04 0C819EB0

The Boot Internal status is:

0x00873300   20000000 6AAF37FF 0CDFD7D2 3B3FFD4F 00000000 00000000 00000000 00000000
0x00873320   00000001 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0x00873340   00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0x00873360   00000000 00000000 00000000 00000000 B588EA1D 1B96BCCC BE3AEB5B D139C6F5
0x00873380   27121466 2C847D0B 4829A026 600E189A AA6F0EBC 5E0083E0 0E01A842 30AC859A
0x008733a0   744B0EC8 92F4108A 8DB3AA98 E457A68E D1474CE7 564083F1 CB41A51C 0C04B26A
0x008733c0   21C8281E D1B94082 D69A2C30 210808CA 1CEC0C10 4290241B 5D1C5285 32EC0820
0x008733e0   D2910D7B DB4C0CA9 D84F0E4D 58142A21 749401F0 44004668 76AB450C 09009992

The Boot Table arguments are:

0x00873400   5171EFA7 D3DEFE7E 2F79DECE 0C05CFAE FC28CF67 BD7FF21A 679B7EFB 019E59E1

The Boot Parameter table is:

0x00873680   00000030 0000001E 05024040 00400000 271009C4 08000800 00000000 B005104C
0x008736A0   00010480 01C90000 23200006 23200002 00000000 00000000 00000000 00000000
0x008736C0   00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0x008736E0   00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

Can anyone help me understand why the PCIe boot isn't working?  

For example,
1) how can the boot log be decoded?
2) the PC is at 0x20b01290.  
    a) What source location does that correspond to in the ROM boot loader?
    b) What is the core waiting for?

Any help is greatly appreciated!

Thanks,
Brad

  • Hi Brad,

    I've notified the sw team. Feedback will be posted here.

    Best Regards,
    Yordan
  • Thank you, Yordan.  I'm looking forward to their response

  • In thread https://e2e.ti.com/support/dsp/c6000_multi-core_dsps/f/639/t/623636 


    Brad,


    We do not release the .out and the .map file for the boot ROM . We only provide the source for reference so you will not be able to debug the ROM code by loading symbols and setting break points. 

    We provide boot examples and boot utilities to convert application to bootable binary. IF you are running into any issues, you can report the Program counter values and run the debug GEL file we provide and check the boot parameter table to see how the boot is progressing.

    Regards,
    Rahul

    Can someone please provide information regarding the boot loader context having program counter at 0x20b01290 in the ROM Bootloader code?
  • Hi,

    Can you clarify if you used TI 6678 EVM or your own board with 6678 for PCIE boot test? It looks the latter, please confirm.

    Also, it looks you used the PCIE boot mode by setting the DEVSTAT register and already adapted the code so there is a stable PCIE link between C6678 and host PC, you are able to write the boot image into DSP L2 address and write the _c_int00 into MAGIC_ADDRESS.

    From bootloader user guide:
    During the boot process, the RBL executes an IDLE command on the secondary
    CorePacs and keeps the secondary CorePacs waiting for an interrupt. After the
    application code to be loaded in these secondary CorePacs are loaded and the
    BOOT_MAGIC_ADDRESS values in individual CorePacs are populated, the
    application code in the CorePac0 can trigger the IPC interrupt to wake up the
    secondary cores and branch up to the address specified in the
    BOOT_MAGIC_ADDRESS.

    Can you try this?

    Regards, Eric
  • Hi Eric,

    Thanks for your reply!  Please find my responses to your questions below.

    Can you clarify if you used TI 6678 EVM or your own board with 6678 for PCIE boot test? It looks the latter, please confirm. 

    Yes, we are using a custom board.  All the results reported are for the custom board.

    Also, it looks you used the PCIE boot mode by setting the DEVSTAT register and already adapted the code so there is a stable PCIE link between C6678 and host PC, you are able to write the boot image into DSP L2 address and write the _c_int00 into MAGIC_ADDRESS. 

    Yes, that's correct.  The link between host and C6678 seems stable and I am able to read/write various memory/registers.  For loading the software I write all the program data to DSP L2 and the _c_int00 address to MAGIC_ADDRESS.

    I have tried issuing legacy interrupts, MSI interrupts and IPC.  Below are the methods used to trigger MSI and IPC:

    /*
    Issues a MSI interrupt
    */
    NTSTATUS triggerMsiInterrupt(PDSP_INFO pDspInfo)
    {
    #define ADDR_MSI_IRQ 0x21800054
    #define ADDR_MSI0_STATUS_RAW 0x21800100
    #define ADDR_EP_IRQ_SET 0x21800064

    UINT32 rval;
    UINT32 buffer;

    buffer = 0;
    rval = writeDSPMemory(pDspInfo, NDX_PCIE_CFG, ADDR_MSI_IRQ, &buffer, (UINT32)sizeof(UINT32));

    buffer = 1;
    rval = writeDSPMemory(pDspInfo, NDX_PCIE_CFG, ADDR_MSI0_STATUS_RAW, &buffer, (UINT32)sizeof(UINT32));

    buffer = 1;
    rval = writeDSPMemory(pDspInfo, NDX_PCIE_CFG, ADDR_EP_IRQ_SET, &buffer, (UINT32)sizeof(UINT32));

    KdPrintEx((DPFLTR_IHVDRIVER_ID, 4, "MSI interrupt triggered. %d bytes written\n", rval));

    return rval;
    }

    NTSTATUS unlockBootConfigMMRs(PDSP_INFO pDspInfo)
    {
    UINT32 rval;
    UINT32 buffer;

    buffer = KICK0_UNLOCK;
    rval = writeDSPMemory(pDspInfo, NDX_CHIP_LEVEL_REGISTERS, CHIP_LEVEL_BASE_ADDRESS+KICK0, &buffer, (UINT32)sizeof(UINT32));

    buffer = KICK1_UNLOCK;
    rval = writeDSPMemory(pDspInfo, NDX_CHIP_LEVEL_REGISTERS, CHIP_LEVEL_BASE_ADDRESS+KICK1, &buffer, (UINT32)sizeof(UINT32));

    return rval;
    }

    NTSTATUS triggerIPC(PDSP_INFO pDspInfo, UINT8 coreNum)
    {
    UINT32 rval;
    UINT32 buffer;

    buffer = 1;
    rval = writeDSPMemory(pDspInfo, NDX_CHIP_LEVEL_REGISTERS, CHIP_LEVEL_BASE_ADDRESS+IPCGR(coreNum), &buffer, (UINT32)sizeof(UINT32));

    return rval;
    }

    During the boot process, the RBL executes an IDLE command on the secondary
    CorePacs and keeps the secondary CorePacs waiting for an interrupt. After the
    application code to be loaded in these secondary CorePacs are loaded and the
    BOOT_MAGIC_ADDRESS values in individual CorePacs are populated, the
    application code in the CorePac0 can trigger the IPC interrupt to wake up the
    secondary cores and branch up to the address specified in the
    BOOT_MAGIC_ADDRESS.

    Can you try this?

    So, you're suggesting to write the program data to each of the CorePacs and then send IPC to each core?  Should IPC be sent to core0, too? Should anything different be done with core0?

    Note: The code I am loading is the ddrInitCode (from pcie_ddr_init_6678.h) provided with the linux bootloader example.  

    Thanks!
    Brad

  • Brad,

    your issue appears to be similar to the issue discussed here:
    e2e.ti.com/.../900106

    You can refer to the code provided from Advantech link for reference.
    There is some MSI interrrupt examples from Advantech support.advantech.com.tw/.../DownloadSRDetail_New.aspx.

    Regards,
    Rahul
  • Thank you, Rahul.  That issue looks a lot like mine. Let me adapt my code and I'll report back with status (I'm working on another issue now so it may be a day or two before I get back to this)

    Thanks,
    Brad

  • Hi Rahul,

    I finally returned to the project! I have adapted my code to upon loading the code to all cores:

    1. Write start address to MAGIC_ADDRESS for each core (0x1087_FFFC | (core << 24))
    2. Issue MSI interrupt on the C6678 PCIe Endpoint by writing 0x1 to EP_IRQ_SET (0x2180_0064)

    Upon writing 0x1 to EP_IRQ_SET, this triggers MSI interrupt on my Windows Host machine.  

    C6678EvtInterruptIsr: MessageID: 0 Interrupt: Message #: 0 VECTOR: 182 IRQL: 11
    C6678EvtInterruptIsr: DSP-1 matches IRQ Vector
    C6678EvtInterruptIsr: DSP-1 EP_IRQ_STATUS [0x00000001]

    C6678EvtInterruptIsr: MessageID: 0 Interrupt: Message #: 0 VECTOR: 101 IRQL: 6
    C6678EvtInterruptIsr: DSP-0 matches IRQ Vector
    C6678EvtInterruptIsr: DSP-0 EP_IRQ_STATUS [0x00000001]


    So, in the Windows driver, the MSI interrupt handler:

    1. Writes 0x1 to EP_IRQ_CLR (0x2180_0068)
    2. Writes 0x4 to IRQ_EOI (0x2180_0050)

    However, when using Blackhawk JTAG debugger, the cores are still sitting at IDLE instruntions - core0 is still at 0x20b0_1290 and cores 1-7 are at 0x20b0_02c8

    I have confirmed that from in the debugger, writing 0x4 to the Interrupt Set Register (ISR) does wake the cores up from IDLE state.

    Is this the correct procedure for waking up PCIe endpoint?

  • I found that writing vector 0 (0x0) to MSI_IRQ (0x54) sent MSI to the C6678 Endpoint and woke the cores from their IDLE state.

    I am resolving this issue as working.