Hello
We're creating a PCIe board for PC using an LS1046A as PCIe endpoint. It doesn't run linux but a proprietary RTOS, you can assume bare-metal. I already set up a BAR and can exchange data with PC (Windows for now, later also linux). But that's only using polling. For better performance I'd like to use interrupts.
PC -> LS1046A: As MSI is not possible I'm writing directly into register MSIIR (0x0158_0000) which triggers an interrupt. However the value in MSIR (0x0158_0004) is always 0x0000_0080, no matter what value I write. Is my understanding wrong that MSIIR can select which bit in which MSIR will be set? Shoould I do it differently?
LS1046A -> PC: I'm looking for code that can send an MSI on LS1046A which works without linux as OS. I saw the pci_endpoint_test.c but it didn't help me that much. Is there some other example code available? Or can somebody describe the necessary steps?
Thanks a lot
Sorry for the multiple posts, they didn't show up on my end and I thought they got lost
I've seen that before and have also studied it, but that didn't really help that much as it's mostly linux-specific config that I don't know how to read. However I seem to got it to work with this:
volatile uint64_t uAddr = m_pPcieReg->m_uMSIAddress + (((uint64_t)m_pPcieReg->m_uMSIAddressUpper) << 32);
volatile uint32_t* volatile pWrite = (uint32_t*)(0x4000000000 + uAddr);
// read configured MSI_Data and write it to MSI_Address (outgoing iATU)
*pWrite = m_pPcieReg->m_uMSIData;
I can't just use any address in a iATU, it must be the one for PCIe (0x40_0000_0000). However that is nowhere explained in the reference manual, it was rather a guess. And only then did I also see that u-boot already set up an outgoing iATU from this address to 0 (on the bus). Maybe a little explanation in the manual might be useful.
(That message got lost or was deleted)
I've seen that before and have also studied it, but that didn't really help that much as it's mostly linux-specific config that I don't know how to read. However I seem to got it to work with this:
volatile uint64_t uAddr = m_pPcieReg->m_uMSIAddress + (((uint64_t)m_pPcieReg->m_uMSIAddressUpper) << 32);
volatile uint32_t* volatile pWrite = (uint32_t*)(0x4000000000 + uAddr);
// read configured MSI_Data and write it to MSI_Address (outgoing iATU)
*pWrite = m_pPcieReg->m_uMSIData;
I can't just use any address in a iATU, it must be the one for PCIe (0x40_0000_0000). However that is nowhere explained in the reference manual, it was rather a guess. And only then did I also see that u-boot already set up an outgoing iATU from this address to 0 (on the bus). Maybe a little explanation in the manual might be useful.
Hi
Here's what I'm trying so far to send an interrupt from EP:
// Enabled Bus_master and Memory_space in Command_register, done in init
// *(volatile uint16*)0x03400004 = 0x0406
// Enabled MSI generation, done in init
// *(volatile uint16*)0x03400052 = 0x0089
// MSI
// with outgoing iATU from 0x015B0000 to 0xFEE00000, MSI_Address = 0xFEE00530)
volatile uint32* pReg = ((uint32*)0x015B0530);
// read configured MSI_Data and write it to MSI_Address (outgoing iATU)
*pReg = *(volatile uint32*)0x034C005C;
// legacy interrupt:
*(volatile uint32*)0x034C002C = 0x00000010;
But so far I couldn't get an interrupt on the driver side (RC) with any method. I assume the driver is correct as it works with other hardware. Is there anything else I need to do? Can the interrupt generation be checked without hardware analyzer?
Please check whether this document would be helpful.
https://community.nxp.com/t5/QorIQ-Knowledge-Base/LS1046A-RDB-in-PCIe-Endpoint-Mode/ta-p/1107415
I've seen that before and have also studied it, but that didn't really help that much as it's mostly linux-specific config that I don't know how to read. However I seem to got it to work with this:
volatile uint64_t uAddr = m_pPcieReg->m_uMSIAddress + (((uint64_t)m_pPcieReg->m_uMSIAddressUpper) << 32);
volatile uint32_t* volatile pWrite = (uint32_t*)(0x4000000000 + uAddr);
// read configured MSI_Data and write it to MSI_Address (outgoing iATU)
*pWrite = m_pPcieReg->m_uMSIData;
I can't just use any address in a iATU, it must be the one for PCIe (0x40_0000_0000). However that is nowhere explained in the reference manual, it was rather a guess. And only then did I also see that u-boot already set up an outgoing iATU from this address to 0 (on the bus). Maybe a little explanation in the manual might be useful.