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.

Questions about implementing local reset across PCIe bus (C6670)

Other Parts Discussed in Thread: TMS320C6670

Hi,

In the C6670 data manual (SPRS689D), the description for the BOOT_ADDR is in Table 3-2 Device State Control Registers. There are no details about whether this register is readable. The table entry is:

0x02620040 0x02620043 4B DSP_BOOT_ADDR0 The boot address for C66x DSP CorePac0

I am finding that if I read this register from a Linux host across the PCIe bus I sometimes get rubbish values and sometimes get a valid value. Is this register readable?

I am renaming my original post and adding new questions to it:

We are basing our code on the TI example found here: C:\TI_MCSDK\mcsdk_2_01_00_03\tools\boot_loader\examples\pcie\linux_host_loader\pciedemo.c

Is this a good example if we want to implement the "Local Reset" as described in section 7.4 Reset Controller of tms320c6670_revD.pdf (TMS320C6670 Data Manual)?

We are finding that writing to the DSP_BOOT_ADDR register does not always seem to work. The Linux host says that it has written to that address and we are doing the kick unlocks as given in the setBootAddrIpcgr function in the TI example. However, looking at that address with CCS shows that instead of the expected value of 0x8f8001, we see the bootROM address of 0x20b00001. It is unclear whether the attempt to write a value to DSP_BOOT_ADDR failed, or whether the value is being overwritten. From slowly removing code from our example it looks like the write is just not working. We do have a scenario where we reset two DSPs, one after the other, and the reset of the second one works and we see the expected value in DSP_BOOT_ADDR so we have seen it work but if we reset only one DSP it does not ever work.

Our scenario is that the DSP boots from SPI and we expect value 0x31D0D in the DEVSTAT register at 0x02620020. After running the reset code we frequently see the value 0x350FF in the DEVSTAT register which does not make sense. Is there any part of the reset example code which could overwrite DEVSTAT?

The reset scenario we need to implement is as follows: When the DSP is powered on, it boots from flash (SPI). Later, the DSP can be running code or can be in an unknown state during normal operation. The Linux host must be able to reset it across the PCIe bus and download code which will run in a loop which watches the magic address then jumps to it if it is populated. Is the TI example quoted above a good way to implement this kind of reset?

In the example, once a value is successfully written to DSP_BOOT_ADDR, what actually tells the DSP to use the value in that register and jump to that code? In the example code, this line causes the code to jump, is that correct:  "myIowrite32(1, pReg + IPCGR(core)/4); "  ?  From the data manual, "The C6670 has four IPCGRx registers (IPCGR0 through IPCGR3) registers. This can be used by external hosts or CorePacs to generate interrupts to other CorePacs. A write of 1 to IPCG field of IPCGRx register will generate an interrupt pulse to CorePacx (0 <= x <= 3)."

How is this interrupt serviced? Do we need to provide some sort of ISR? We are not setting up any interrupt sources. Where will the code go?

Thanks,
Geraldine

  • I have created a simpler test. From the Linux host, I have a module which does not try to do any kind of reset. Instead it only does the following:

    Unlock KICK0, KICK1.
    Write an address 0x8a8a80 to BOOT_ADDR (0x02620040).
    Re-lock KICK0, KICK1.

    On the DSP I load a very simple project using CCS which reads address 0x02620040 in a loop and prints its contents.

    Expected results:

    When the DSP simple project is running and the Linux host module is run, the contents of 0x02620040 should change.

    Actual results:

    1. Cycle power. Run the test. The results are as expected except that 0x02620040 contains 0x8a8801 instead of 0x8a8a80.

    [Edit: Ignore this test. Doing a "System Reset" kills the PCIe link. Sorry...] 2. After running test 1 above, use CCS to do a "System Reset" which sets the contents of 0x02620040 to a BootROM address 0x20b00001. Unload the Linux module and re-run the test. This time the contents of 0x02620040 do *not* change, they still contain the BootROM address 0x20b00001.

    [Edit: Ignore this test. Doing a "System Reset" kills the PCIe link. Sorry...] 3. Cycle power. Load and run the DSP simple project and then do a CCS "System Reset". Now run the test. This time the contents of 0x02620040 do *not* change, they still contain the BootROM address 0x20b00001.

    4. Cycle power. Run the test. The results are as expected except that 0x02620040 contains 0x8a8801 instead of 0x8a8a80. Manually change the contents of the KICK0 and KICK1 registers so that it is possible to manually change the contents of 0x02620040. Set the contents of 0x02620040 to the BootROM address 0x20b00001. Unload the Linux module and re-run the test. This time the contents of 0x02620040 do *not* change, they still contain the BootROM address 0x20b00001.

    [Edit] Subsequent testing without stupidly killing the PCIe link still shows that the register 0x02620040 can be written only once after a power cycle by the Linux host. It can be written multiple times by the DSP but not by the host.

    The only way I have found for the Linux module to be able to change the contents of 0x02620040 is for it to do it after a power cycle and without CCS doing its "System Reset". What is causing this? How can I ensure that the Linux module can write to 0x02620040? This is a *requirement* to be able to get the reset working.

    Thanks,
    Geraldine

  • Useful info which I found in another post (http://e2e.ti.com/support/dsp/c6000_multi-core_dsps/f/639/t/253724.aspx):

    DSP_BOOT_ADDRn will hold the 22 MSBs (bits31-10) of the CorePac boot address. bits9-0 are reserved in this register. The reset value is 22 MSBs of 0x20b00000.

    We will add this piece of info in the next release of C66x data manuals. And CorePac will jump to the address specified in DSP_BOOT_ADDRn register automatically after out of reset. It is not software controlled (hardware controlled, not by RBL).

  • Hi - does anyone have some ideas about how to resolve this?

    Thanks,
    Geraldine

  • Geraldine,

    Have you tried to change the “MST_PRIV” bit to 1 in PRIORITY register on the target PCIe device (0x2180003c, section 3.1.14 in PCIe user guide) please?

    After that the PCIe port will be configured as "supervisor mode" which is required to access some chip-level configuration registers.

    There are some similar issues, such as follows:

     http://e2e.ti.com/support/dsp/c6000_multi-core_dsps/f/639/p/131840/480784.aspx#480784

    Please give a try to see if it is working for you. 


  • Steven,

    Yes, we always change the “MST_PRIV” bit to 1 in the PRIORITY register on the target PCIe device before writing to the DSP boot address register. Is there something else we could try? The link you provided in your post gives an error when I click on it.

    Thanks,
    Geraldine

  • Geraldine,

    After power cycle DSP, the PCIe of DSP is ready for the link up. Once you run the test on Linux host side, both RC and EP could get link up and you can modify the BOOT_ADDR register. Is it correct?

    But when you "Unload the Linux module and re-run the test" on Linux host side, I am thinking the link might be down or not stable.

    Could you confirm there is still PCIe link up between RC and EP please (LTSSM_STAT=0x11 in DEBUG0 register 0x21801728 in DSP)? Are you able to access other DSP memory from Linux Host via PCIe in the same scenario please?