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.

AM5728: Missing interrupts

Part Number: AM5728


AM5728, PDK 1.0.2, Compiler V8.1.0, BIOS 6.45.1.29, XDC 3.32.0.06

Using the AM5728 on a custom board.  DSP core running SYS/BIOS.  Talking to an FPGA via PCIe,
which seems to be working.  The DSP sends a command to the FPGA and upon completion the FPGA
sends an interrupt to the DSP via GPIO8_8.  Commands are sent in groups of 4 every 570 usec.
Commands are spaced apart by ~74 usec. Each command results in two interrupts, which are ~28 usec
apart.

This seems to be working but I miss about 1 out of 100 interrupts.  My code can detect a missed
interrupt via timeout.  When I miss an interrupt I set a GPIO high allowing me to capture the
event on a storage scope or logic analyzer.  I added a toggle of another GPIO in the interrupt
handler callback function for the GPIO.  I can see that in the case of the missed interrupt that
GPIO does not toggle, but the scope shows the interrupt and it looks as good as good interrupts,
leading me to believe the AM5728 is actually missing the interrupt.

The GPIO is configured for rising edge interrupt.  The level is 1.72v and the pulse lasts ~30 nsec.

I was thinking that maybe something is occasionally disabling interrupts, so I set a breakpoint
in the HWI function Hwi_disableInterrupt() but that was never hit, so I don't think that is the
issue. 

Any ideas/recommendations on how to troubleshoot this further?

  • Moving this to the Sitara forum.

    Best Regards,
    Yordan
  • Thank you. When I put in the part number AM5728 under the posting form, it automatically selected the Keystone Forum and I could not change it. I think that's a bug.
  • Hi,

    Can you explain "and upon completion the FPGA sends an interrupt to the DSP via GPIO8_8", how this works? Is it a PCIE MSI or legacy interrupt? If yes, this interrupt can go to DSP CPU via crossbar, how it is latched to GPIO8_8? Or, the FPGA pokes GPIO register on the DSP side, throught PCIE interface to generate interrupt?

    "The GPIO is configured for rising edge interrupt. The level is 1.72v and the pulse lasts ~30 nsec."===> How the interrupt signal come from?

    What is the speed of PCIE interrface (GEN2, x2 lane)? Will increase the interface speed or reduce the interrupt occurrence help? Can the ISR miss the interrupt (assuming during the process, the interrupt is disabled when the next one comes)?

    Regards, Eric
  • The GPIO is connected to a dedicated interrupt hardware signal from the FPGA. I guess I need to explain more fully.

    We ran out of SPI connections in our design, so we implemented a SPI Master in the FPGA that talks SPI to another board in our system. A command is sent over PCIe to the FPGA to initiate a SPI transaction. At that time the PCIe is done, so I do not believe this has anything to do with PCIe. When the FPGA starts the SPI transaction it sends the DSP an interrupt, via the dedicated HW line to GPIO8_8. The DSP gets the interrupt and moves to the next stage of processing. When the FPGA completes the SPI transaction, the DSP gets the interrupt and reads a result from the FPGA over PCIe. The DSP pends (with timeout ~2 msec) on each of these expected interrupts. The pend times out the interrupt was missed. I see these pend timeouts about 1% of the time.

    To troubleshoot, I added a GPIO output that indicates when I got the pend timeout (error condition) and another GPIO that indicates when the GPIO callback function is called. On the oscilloscope I monitored the SPI Chip Select out of the FPGA, the hardware interrupt line from the FPGA to the 5728, the error GPIO and the interrupt callback GPIO. When the error occurs I can look back in time and see the FPGA sent both interrupts as expected, both as good looking pulses, but the DSP did not call the callback function (no callback GPIO activity).

    So, from that test I concluded that somehow the 5728 is missing the interrupt and the GPIO callback function is not being called. I did not see any other error cases that did not follow this observed process.
  • Your last question about the ISR missing the interrupt. I will try to look at that. The ISR has to read an interrupt register from the FPGA via PCIe to figure out which interrupt occurred, then it posts to the pending semaphore. I suppose if somehow that read or post got delayed by a significant amount, > 28 usec, the second interrupt could be missed.

  • I set a GPIO high when I start the ISR and set it low when the ISR completes. From the HW interrupt to the start of the ISR is 1 usec, the ISR executes for 4.75 usec, the time to next ISR is about 22 usec. When I get my timeout condition, the ISR does not execute and the previous ISR completed over 300 usec earlier. So, this is not a case of the ISR executing past the next interrupt. However, this is in my callback code. I'd have to edit HWI code to get closer to the spots the interrupts are enabled/disabled.
  • Moved onto some other testing and measured that I am missing about 0.2%-0.4% of the interrupts at an interrupt rate of about one interrupt every 600 usec. I have another mode where I have 9 interrupts every 600 usec and that miss rate is about the same.

    Measured on the oscilloscope I see it takes between 2.44 usec and 5.0 usec for the callback routine to execute from the HW interrupt going high. We are going to attempt to put a catch in the FPGA such that if the DSP has not read the FPGA Interrupt status register within a 6 usec window, the FPGA will reassert the interrupt. Our system can not function with missed interrupts, so we have to do something to be sure we get every interrupt.
  • We made a mod to the interrupt generator in the FPGA. If the DSP does not read the interrupt status register within 5 usec, the FPGA will re-assert the interrupt. With this change my system operates normally. This helps to confirm that the 5728 in indeed missing interrupts. I'd really like to get this fixed correctly, so any advice on troubleshooting this further would be appreciated.
  • Hi,

    Sorry for the late response! From my reading of your system, DSP -------PCIE interface-----FPGA (SPI master) ----- SPI interface---- another board(SPI slave). The first GPIO interrupt happens when SPI transfer starts and the second happens when transfer finished (28 us later). The GPIO callback ISR execution takes about 5us, this is still plenty of room for the second ISR. But in between there is a DSP read from FPGA over PCIE to determine which interrupt occurred, then it posts to the pending semaphore. This caused long delay and missing interrupt.

    Your workaround is FPGA to regenrate GPIO interrupt if DSP didn't read it after 6 us and problem resolved.

    So what is the speed and lane width of the PCIE? Do you have any other (heavy) traffic on the PCIE bus? Reading the FPGA is only a 32-bit read of one register or a bunch of registers? If it is the latter, you may consider to use EDMA, otherwise it is not helpful. Do you have any measurement of PCIE read latency? In the past we measured the PCIE read latency on other TI PCIE devices (Keystone), it is about 1us. Although I don't have the data for this AM5728 device, but I don't believe it can reach as high as 20us.

    Another thing is when the PCIE read starts relative to the beginning of the first ISR? Is possible the read is issued late? Is it possible to use a hardware timer interrupt to genearte the PCIE read? pending semaphore I guess there is almost no delay?

    Regards, Eric
  • Hello Eric,

    I will try to reply to all your questions.

    You said, "This caused long delay and missing interrupt."  The long delay is caused by the missing interrupt.  Because we miss the interrupt the semaphore never gets posted and the wait times out.

    "Your workaround is FPGA to regenrate GPIO interrupt if DSP didn't read it after 6 us and problem resolved."  Correct

    So what is the speed and lane width of the PCIE? 1 lane at 5G

    Do you have any other (heavy) traffic on the PCIE bus? No, this is the only thing going on.  I know the PCIe reads are completing quickly and reliably.  The problem is the DSP never sees the interrupt no matter how long I wait for it.

    Reading the FPGA is only a 32-bit read of one register or a bunch of registers? One register read.

    Do you have any measurement of PCIE read latency? Right now, no, but I'm sure my testing has proven that the problem is the DSP core never gets the interrupt in the first place, so the PCIe read is secondary to that.

    Another thing is when the PCIE read starts relative to the beginning of the first ISR?

    Is possible the read is issued late? No

    Is it possible to use a hardware timer interrupt to genearte the PCIE read? No, since I did not get the interrupt in the first place I would not know to regenerate a PCIE read.

    pending semaphore I guess there is almost no delay? Not sure what you are asking here.

    The bottom line is this.  I see in hardware an interrupt from the FPGA to the 5728, but the DSP core never calls the GPIO callback function.  The DSP core is missing the interrupt.  My post from Dec 15th I think describes this pretty well.

    Hopefully that helps to clarify what we are seeing happening.

    Thanks,

    Chris

  • Chris,

    Thanks for the explanation! Then the PCIE is not the problem in the system. The issue came from DSP loss the GPIO interrupt occasionally.

    What software you used to configure the GPIO interrupt? We have a GPIO driver under Processor RTOS SDK, which has a test of toggle LED on our EVMs. It used rising edge interrupt as well with a callback registered. Do you follow the same example?

    As the DSP missed interrupt instead of counted some spurious interrupt, I think the debounce will not help. Would you able to try if using the falling edge or level to trigger interrupt or if you can make the interrupt pulse longer (pulse lasts ~30 nsec) to see if it helps?

    Regards, Eric
  • Eric,

    I did follow closely the example code from the Processor SDK. I configure all my GPIO pins in the GPIO_PinConfig structure. For this pin in particular the code is

    GPIO_DEVICE_CONFIG(DSP1_FPGA_DSP_IRQ1_PORT_NUM,DSP1_FPGA_DSP_IRQ1_PIN_NUM) | GPIO_CFG_IN_INT_RISING | GPIO_CFG_INPUT,

    I call the GPIO_init() function, then setup the crossbar, then call GPIO_setCallback for the interrupt pins.

    That is about it. Pretty simple really. The interrupts are working 98% of the time, so it is not likely a config issue.

    The interrupt pulse was extended from 30 nsec to 70 nsec currently. I did not see any decrease in the interrupt miss rate when we extended the pulse. Since the interrupt is edge triggered, that did not surprise me.

    Chris
  • Chris,

    Yes, the GPIO driver is simple. Will using GPIO_CFG_IN_INT_FALLING or level (GPIO_CFG_IN_INT_LOW or GPIO_CFG_IN_INT_HIGH) or using the second GPIO interrupt line (GPIO_INT_LINE_2) help?

    Regards, Eric
  • My initial config was RISING edge. I tried FALLING and HIGH with no change in missed interrupts. I do not see how to change interrupt lines as you asked. The driver code seems to be setup for INT_LINE_1. I don't see any way to override that from outside the driver.
  • Hi,

    Let me find a way to test the GPIO standalone in DSP with ~20 us interrupt trigger interval, to see if we miss any interrupt. Will let you know.

    Regards, Eric
  • Hi,

    I saw you used PDK 1.0.2 which is old, please use the latest PDK 1.0.5. GPIO driver is quite simple, I am not sure if any release change can improve the performace.

    There is a GPIO_LedBlink_evmAM572x_c66xTestProject runs on DSP to toggle LED with GPIO callback. I modified this and added counter to trigger 10,000 interrupts at 12,000 cycles (corrsponding to 20us with 600MHz DSP CPU) interval and count how many times callback is invoked. I saw the same 10,000 times, there is no interrupt loss at 20 us interval. Attached is my updated test code

    /**
     *  \file   main.c
     *
     *  \brief  Example application main file. This application will toggle the led.
     *          The led toggling will be done inside an callback function, which
     *          will be called by Interrupt Service Routine. Interrupts are
     *          triggered manually and no external source is used to trigger
     *          interrupts.
     *
     */
    
    /*
     * Copyright (C) 2014 - 2016 Texas Instruments Incorporated - http://www.ti.com/
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * Redistributions of source code must retain the above copyright
     * notice, this list of conditions and the following disclaimer.
     *
     * Redistributions in binary form must reproduce the above copyright
     * notice, this list of conditions and the following disclaimer in the
     * documentation and/or other materials provided with the
     * distribution.
     *
     * Neither the name of Texas Instruments Incorporated nor the names of
     * its contributors may be used to endorse or promote products derived
     * from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     */
    
    
    #ifndef BARE_METAL
    /* XDCtools Header files */
    #include <xdc/std.h>
    #include <xdc/cfg/global.h>
    #include <xdc/runtime/System.h>
    #include <xdc/runtime/Error.h>
    
    
    /* BIOS Header files */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    #endif
    
    #include <stdio.h>
    
    /* TI-RTOS Header files */
    #include <ti/drv/gpio/GPIO.h>
    #include <ti/drv/gpio/soc/GPIO_soc.h>
    
    #include "GPIO_log.h"
    #include "GPIO_board.h"
    
    #include <ti/board/board.h>
    #include <c6x.h>
    
    /**********************************************************************
     ************************** Macros ************************************
     **********************************************************************/
    #if defined(SOC_AM572x) || defined (SOC_AM571x)
    #if defined (__TI_ARM_V7M4__)
    #define DELAY_VALUE       (0x6FFFFFU) /* Update Delay as it is not sufficent for M4 core */
    #else
    #define DELAY_VALUE       (0x6FFFFFU)
    #endif
    #else
    #define DELAY_VALUE       (0x6FFFFFU)
    #endif
    
    /**********************************************************************
     ************************** Internal functions ************************
     **********************************************************************/
    
    /* Delay function */
    void AppDelay(unsigned int delayVal);
    
    /* Callback function */
    void AppGpioCallbackFxn(void);
    
    #if defined(IDK_AM572X) || defined(IDK_AM571X)
    /* GPIO clock and pinmux configurations */
    extern void AppGPIOInit(void);
    #endif
    
    #if defined(IDK_AM572X)
    extern void GPIOApp_UpdateBoardInfo(void);
    extern void GPIOAppUpdateConfig(uint32_t *gpioBaseAddr, uint32_t *gpioPin);
    #endif
    
    /*
     *  ======== Board_initI2C ========
     */
    static void Board_initGPIO(void)
    {
        Board_initCfg boardCfg;
    
    #if defined(SOC_K2H) || defined(SOC_K2K) || defined(SOC_K2E) || defined(SOC_K2L) || defined(SOC_K2G) || defined(SOC_C6678) || defined(SOC_C6657)
        GPIO_v0_HwAttrs gpio_cfg;
    
        /* Get the default SPI init configurations */
        GPIO_socGetInitCfg(GPIO_LED0_PORT_NUM, &gpio_cfg);
    
        /* Modify the default GPIO configurations if necessary */
    
        /* Set the default GPIO init configurations */
        GPIO_socSetInitCfg(GPIO_LED0_PORT_NUM, &gpio_cfg);
    
    #if defined(SOC_K2G)
        /* Setup GPIO interrupt configurations */
        GPIO_socSetIntMux(GPIO_LED0_PORT_NUM, GPIO_LED0_PIN_NUM, NULL, GPIO_MUX_SEL);
    #endif
    #endif
    
    #if defined(EVM_K2E) || defined(EVM_C6678)
        boardCfg = BOARD_INIT_MODULE_CLOCK |
            BOARD_INIT_UART_STDIO;
    #else
        boardCfg = BOARD_INIT_PINMUX_CONFIG |
            BOARD_INIT_MODULE_CLOCK |
            BOARD_INIT_UART_STDIO;
    #endif
        Board_init(boardCfg);
    
    #if defined(IDK_AM572X)
        GPIOApp_UpdateBoardInfo();
    #endif
    }
    
    /**********************************************************************
     ************************** Global Variables **************************
     **********************************************************************/
    volatile uint32_t gpio_intr_triggered = 0, callback_counter = 0;
    uint32_t gpioBaseAddr;
    uint32_t gpioPin;
    
    /*
     *  ======== test function ========
     */
    #ifndef BARE_METAL
    void gpio_test(UArg arg0, UArg arg1)
    {
    #else
    void main()
    {
        Board_initGPIO();
    #endif
        uint32_t testOutput = 1;
        uint32_t loop = 0;
    
        /* GPIO initialization */
        GPIO_init();
    
        /* Set the callback function */
        GPIO_setCallback(USER_LED0, AppGpioCallbackFxn);
    
        /* Enable GPIO interrupt on the specific gpio pin */
        GPIO_enableInt(USER_LED0);
    
        /* Write high to gpio pin to control LED1 */
        GPIO_write((USER_LED1), GPIO_PIN_VAL_HIGH);
        AppDelay(DELAY_VALUE);
    
        GPIO_log("\n GPIO Led Blink Application \n");
    
    #if defined(SOC_K2L) || defined(SOC_C6678) || defined(SOC_C6657)
        /* No GPIO pin directly connected to user LED's on K2L/K2G/C6678/C6657 EVM, just trigger interrupt once */
        GPIO_toggle(USER_LED0);
        while (!gpio_intr_triggered);
    
        GPIO_log("\n All tests have passed \n");
    #else
    
        while(loop < 10000)
        {
    #if defined(SOC_AM572x) || defined(SOC_AM571x)|| defined(SOC_AM335x) || defined(SOC_AM437x)
    
    #if defined (IDK_AM572X)
            /* Update GPIO info based on the board */
            GPIOAppUpdateConfig(&gpioBaseAddr, &gpioPin);
    #else
            gpioBaseAddr = GPIO_BASE_ADDR;
            gpioPin      = GPIO_LED_PIN;
    #endif
            /* Trigger interrupt */
            GPIOTriggerPinInt(gpioBaseAddr, 0, gpioPin);
    #endif
    #if defined(SOC_K2H) || defined(SOC_K2K) || defined(SOC_K2E) || defined(SOC_K2G)
            GPIO_toggle(USER_LED0);
    #endif
            AppDelay(12000);
            loop ++;
        }
    #endif
        Task_exit();
    }
    
    #ifndef BARE_METAL
    /*
     *  ======== main ========
     */
    int main(void)
    {
        /* Call board init functions */
    	TSCL = 1;
        Board_initGPIO();
    
    #if defined(IDK_AM572X) || defined(IDK_AM571X)
        AppGPIOInit();
    #endif
    
        /* Start BIOS */
        BIOS_start();
        return (0);
    }
    #endif
    
    /*
     *  ======== AppDelay ========
     */
    void AppDelay(unsigned int delayVal)
    {
    	uint32_t start = TSCL;
    
    	while ((TSCL - start) < delayVal);
    }
    
    /*
     *  ======== Callback function ========
     */
    void AppGpioCallbackFxn(void)
    {
        /* Toggle LED1 */
        //GPIO_toggle(USER_LED1);
        AppDelay(12000);
        gpio_intr_triggered = 1;
        callback_counter ++;
    }
    
    
    
    . This still uses rising edge and the first interrupt lane.

    If you can verify the GPIO standalone doesn't missing interrupt is good, also please try to upgrade to PDK 1.0.5 release.

    Let me know your finding.

    Regards, Eric

  • Before switching to 1.0.5, which is kind of a pain since I have modified some files, I wanted to try to reproduce your test on our hardware. I can stimulate an interrupt from the FPGA by writing to a control register. This is a PCIe write, but a memory write only and not resulting in an interrupt of any kind. After I write to the FPGA, the DSP pends on a semaphore waiting on the interrupt. The interrupt posts to the semaphore. This is inside a while(1) loop, so nothing else is running, no interrupts of any kind. At the end of the while loop I also added a delay in usec to get the desired interrupt repeat time. The results are as follows:

    With a 29 usec interrupt time, no missed interrupts.
    With a 24 usec interrupt time, no missed interrupts.
    With a 19 usec interrupt time, missed 16 out of 11,049,488 interrupts.
    With a 14 usec interrupt time, missed 80 out of 10,423,594 interrupts.
    With a 9 usec interrupt time, missed 7 out of 10,061,528 interrupts.

    9 usec is the lowest rate I can acheive with this test setup. Interesting how the rate went down again. The delay
    function I am using just checks Timestamp_get32() for a count value that many ticks in the future, so I would not
    have expected it to affect the results, but the 9 usec test does not call the delay function.
  • Hi,

    I updated my delay to 8400 cycles to simulate 14 us interrupt in while loop, also in the callback function I only left the counter increment code. I believe this is the cloest to your system.

    I did a loop of 10M times, I didn't miss any interrupt.

    You reported less loss ration in PDK 1.0.5 vs PDK 1.0.2 (1% loss), do you know if this because of PDK version or something else changed in your system/code?

    Regards, Eric
  • Ok, so I switched to PDK 1.0.5 (the tests above were with PDK 1.0.2), and the error rate seemed about the same.

    Then I loaded a new dsp image file to the eMMC via WinSCP via USB 3.0, while the test was running and the error jumps dramatically...

    During the 3 second file transfer time I got 310 missed interrupts. After the file transfer concluded, the missed interrupt rate went back to normal. Note, that we have Linux running on the ARM, so in theory this should not have impacted the DSP at all.

    You asked above why the missed interrupt rate seemed to decrease for this test. Well, for this test, I was not doing any of the PCIe transfers that were occurring during the previous test. Those transfers are from PCIe to L2SRAM, then the data in L2SRAM is processed and written to DDR.

    The error rate jumps dramatically when I cat a large file from the eMMC filesystem.

    So, this observation of the dramatic jump in error rate when doing file access is very interesting. It would seem that the DSP performance is being directly impacted by external memory activities.
  • So, things have taken an interesting and unexpected turn. I now believe the problem is that the ARM was also trying to service this interrupt at the same time. I tried to observe the status bits being set for the GPIO bank and they never were. Clearly they must be sometimes or it would never work. When I disabled the interrupt in the GPIO I then saw the RAW status bit being set. Then it dawned on me that the ARM is running also. I connected the debugger to the ARM and halted it and voila, the missing interrupts went away. So, I have contacted our ARM developers and told them we need to stop the ARM from trying to service the GPIO8 interrupt. GPIO8 has no inputs the ARM cares about, so I am not sure why it is trying to service this interrupt.

    However, this has led me to another problem I am going to encounter in the future. GPIO8 has interrupts that are supposed to be serviced by each DSP core. For example, GPIO8_8 is serviced by DSP1 and GPIO8_20 is serviced by DSP2. The current TI GPIO driver clears all the GPIO status bits when it gets the interrupt. So, if GPIO8_8 and GPIO8_20 happen to occur at the same time (they are completely independent so I can't ensure this won't happen) the first DSP will read the GPIO8 Interrupt Raw Status and clear ALL the bits which will make the other DSP see no bits set. This is not going to work for me. The ISR needs to only clear the bits it is setup to care about. I guess I am going to have to rewrite GPIO_v1.c. But that is a conversation for another day.
  • Hi,

    Good to know that you found both ARM and DSP served the same GPIO interrupt. As the "The current TI GPIO driver clears all the GPIO status bits when it gets the interrupt", I will look at this and raise this to our development team.

    Regards, Eric

  • Thanks Eric, I'd appreciate that.

    The current GPIO HWI has this code:

    /* Find out which pins have their interrupt flags set */
    gpioPins = GPIORawIntStatus(gpioBase, intrLineNum, GPIO_PIN_MASK_ALL);

    /* Clear all the set bits at once */
    GPIOIntrClearMask(gpioBase, intrLineNum, gpioPins);

    /* Match each set bit to its corresponding callback function */
    while (gpioPins) {
    /* Gets the lowest order set bit number */
    bitNum = getPinNumber(gpioPins);
    gpioIndex = portCallbackInfo->pinIndex[bitNum];
    if (gpioIndex != CALLBACK_INDEX_NOT_CONFIGURED) {
    GPIO_v1_config.callbacks[gpioIndex]();
    }
    gpioPins &= ~(((uint32_t)1U) << bitNum);
    }

    I was considering changing it to this:

    /* Find out which pins have their interrupt flags set */
    gpioPins = GPIORawIntStatus(gpioBase, intrLineNum, GPIO_PIN_MASK_ALL);

    /* Match each set bit to its corresponding callback function */
    while (gpioPins) {
    /* Gets the lowest order set bit number */
    bitNum = getPinNumber(gpioPins);
    gpioIndex = portCallbackInfo->pinIndex[bitNum];
    if (gpioIndex != CALLBACK_INDEX_NOT_CONFIGURED) {
    GPIO_v1_config.callbacks[gpioIndex]();
    /* Clear only the pins we serviced */
    GPIOIntrClearMask(gpioBase, intrLineNum, ((uint32_t)1U) << bitNum);
    }
    /* Clear the pins we checked for service
    gpioPins &= ~(((uint32_t)1U) << bitNum);
    }

    You have to consider the case where you have two different processors configured to get two different interrupts on the same GPIO bank. The pinIndex array would (has to be) different. So processor 1 can service what it cares about and leave behind what processor 2 cares about.

    There is also a concern, and the code change above might make that worse, what happens if a second GPIO interrupt occurs after the status is read but before the current ISR completes. I don't yet know how that would play out.