AM6442: issues setting up MAIN_GPIOMUX_INTROUTER

Part Number: AM6442

Hello,

I'm trying to route one GPIO interrupt (example: GPIO1_57, directly, not the banked outputs) to a certain core (example ICSSG1 subsystem, event 46+64), I tested these two possible paths:

1- Using Sciclient_rmIrqSet:

{

    int32_t                             retVal;
    struct tisci_msg_rm_irq_set_req     rmIrqReq;
    struct tisci_msg_rm_irq_set_resp    rmIrqResp;
    rmIrqReq.valid_params           = 0U;
    rmIrqReq.valid_params          |= TISCI_MSG_VALUE_RM_DST_ID_VALID;
    rmIrqReq.valid_params          |= TISCI_MSG_VALUE_RM_DST_HOST_IRQ_VALID;
    rmIrqReq.global_event           = 0U;
    rmIrqReq.src_id                 = TISCI_DEV_GPIO1;
    rmIrqReq.src_index              = 57;
    rmIrqReq.dst_id                 = TISCI_DEV_PRU_ICSSG1;
    rmIrqReq.dst_host_irq           = 46;
    rmIrqReq.ia_id                  = 0U;
    rmIrqReq.vint                   = 0U;
    rmIrqReq.vint_status_bit_index  = 0U;
    rmIrqReq.secondary_host         = TISCI_MSG_VALUE_RM_UNUSED_SECONDARY_HOST;

    retVal = Sciclient_rmIrqSet(&rmIrqReq, &rmIrqResp, SystemP_WAIT_FOREVER);
    if(0 != retVal)
    {
        DebugP_log("[Error] Sciclient event config failed!!!\r\n");
        DebugP_assert(FALSE);
    }
    return;
}
2- Or using Sciclient_rmIrqSetRaw:
{
    int32_t                             retVal;
    struct tisci_msg_rm_irq_set_req     rmIrqReq;
    struct tisci_msg_rm_irq_set_resp    rmIrqResp;
    rmIrqReq.valid_params           = 0U;
    rmIrqReq.valid_params          |= TISCI_MSG_VALUE_RM_DST_ID_VALID;
    rmIrqReq.valid_params          |= TISCI_MSG_VALUE_RM_DST_HOST_IRQ_VALID;
    rmIrqReq.global_event           = 0U;
    rmIrqReq.src_id                 = TISCI_DEV_MAIN_GPIOMUX_INTROUTER0;
    rmIrqReq.src_index              = 80+57;
    rmIrqReq.dst_id                 = TISCI_DEV_MAIN_GPIOMUX_INTROUTER0;
    rmIrqReq.dst_host_irq           = 46;
    rmIrqReq.ia_id                  = 0U;
    rmIrqReq.vint                   = 0U;
    rmIrqReq.vint_status_bit_index  = 0U;
    rmIrqReq.secondary_host         = 0U;

    retVal = Sciclient_rmIrqSetRaw(&rmIrqReq, &rmIrqResp, SystemP_WAIT_FOREVER);
    if(0 != retVal)
    {
        DebugP_log("[Error] Sciclient event config failed!!!\r\n");
        DebugP_assert(FALSE);
    }
    return;
}
In addition I have the following exclusing in both u-boot and kernel's dts:
&main_gpio1 {
    status = "reserved";
};
&main_gpio_intr {
    status = "reserved";
};
I also added this to rm-cfg.yaml for my board:
        -
            start_resource: 46
            num_resource: 1
            type: 192
            host_id: 51
            reserved: 0
and increased resasg_entries_size by 8. Also note that GPIO1, ICSSG1 and MAIN_GPIOMUX_INTRTR0 are all powered up.
 
I have errors with both approches (err -19). Could you please review the above and let me know what is missing / wrong.
Thank you.
 
  • Hello there,

    I will need to send your question over to another team member to discuss the errors from your MCU+ settings. But before I do that, let's talk about your design. What are you trying to do with the PRU subsystem?

    I definitely expect you to be able to configure an interrupt from a GPIO pin and send it to the PRU subsystem's INTC. Then the PRU core could either poll the R31 register to see that an interrupt was received, or you could configure the Task Manager to preempt currently running code when an interrupt is received. But if latency matters, I typically see people directly connect signals to one of the PRU's GPI signals, which allows the PRU core to detect the signal going high or low within just a few PRU clock cycles.

    Separately, the team has done a lot of good work putting together new resources for PRU developers over the past year (like the PRU Academy and OpenPRU repo). Let me know if you'd like pointers to additional resources.

    Regards,

    Nick

  • Hello Nick,

    Thank you for your quick note, indeed the PRU is not at the heart of the question. In this particular example, the GPIO pin interrupt triggers a tasks manager (INTC routing within the PRUSS) where latency is not an issue.

    An additional information and question: I'm also using Sciclient_rmIrqSetRaw() for timesync_int_router and it works without any issues and without having any entries in rm-cfg.yaml: is it safe to say that if I use Sciclient_rmIrqSetRaw() I bypass rm-cfg check?, here's an example of my timesync int routing that works without any resag_entry of "type: 384".

            req.valid_params = TISCI_MSG_VALUE_RM_DST_ID_VALID | TISCI_MSG_VALUE_RM_DST_HOST_IRQ_VALID;
            req.src_id = TISCI_DEV_TIMESYNC_EVENT_INTROUTER0;
            req.dst_id = TISCI_DEV_TIMESYNC_EVENT_INTROUTER0;
            req.src_index = (uint16_t)CSLR_TIMESYNC_EVENT_INTROUTER0_IN_PINFUNCTION_CPTS0_HW1TSPUSHIN_CPTS0_HW1TSPUSH_0;
            req.dst_host_irq = 16u; /* TIMESYNC_EVENT_INTROUTER0_outl_16 -> CPTS0_cpts_hw1_push */
            status = Sciclient_rmIrqSetRaw(&req, &resp, SystemP_WAIT_FOREVER);
    So why is SYSFW not acknowledging Sciclient_rmIrqSetRaw() for TISCI_DEV_MAIN_GPIOMUX_INTROUTER0 but it is happily accepting it for TISCI_DEV_TIMESYNC_EVENT_INTROUTER0?
    Thank you.
  • Additional info: 

    I can read MAIN_GPIOMUX_INTROUTER0 PID register content (0x66948100) but I can't write to any of the output registers: tried to configure it independently from SYSFW by directly writing 0x00010093 (selecting input 147) to address 0x00A000BC (output 46): this causes a data abort interrupt on R5F0_0, does SYSFW reserves the access to MAIN_GPIOMUX_INTROUTER0 only from DMSC, I tried the same approach with other routers timesync event rtr and cmp event rtr: I successfully configure the output mux ctrl, so these are not protected in the same manner?.

    Since all 3 routers are all on the same firewall zone : ID34, region 8, I don't see how one can be locked but not the 2 others.

    Note that I'm usingthe default SDK's sec_cfg.yaml for the evm board.

  • Hello,

    If latency is not an issue, then your design is probably fine. I am going to send your thread over to my team member now.

    Initial AI-assisted thoughts

    While we are waiting for my team member to comment, I'll attach some input from one of my AI tools. Perhaps it will be useful.

    Regards,

    Nick

  • Summary of what I can confirm vs. what I can't

    Three concrete problems are visible in the code/config; the firewall-zone question and the exact meaning of -19 are not covered by the documentation I retrieved — flagged at the end.


    1. The source index is wrong in both calls

    GPIO1_GPIO_OUT_57 is wired to MAIN_GPIOMUX_INTROUTER0_IN_IN_147 1, confirmed independently by the input-side interrupt table 2.

    • Raw call uses src_index = 80+57 = 137 → wrong. It must be 147.
    • Non-raw call (src_id = TISCI_DEV_GPIO1, src_index = 57) is the abstracted form and should be correct for the source side, so its failure points at the destination/ownership side (item 2).

    Note the customer's own direct register write used 0x00010093 (= input 147), i.e. the register-level value was right while the TISCI src_index was not.

    An existing E2E case with this exact -19 symptom was resolved by correcting the GPIO source index in the raw route parameters 3.

    2. Output 46 ownership / reachability

    Two independent checks are required and both must pass:

    Check What to verify
    Output physically reaches ICSSG1 MAIN_GPIOMUX_INTROUTER0 outputs fan out to DMSC, GICSS, R5F cores, DMASS and PRU-ICSSG destinations — confirm from the output map that out_46 is the line landing on ICSSG1 event 46+64, not an output wired elsewhere 4
    RM allocation The router output must be allocated in the RM board config to the host involved in the route; the documented failure mode is exactly "requesting core is not assigned the selected MAIN_GPIOMUX_INTROUTER0 output," fixed by reassigning the output and rebuilding the board config + SBL 5

    Additional ownership traps that produce the same rejection:

    • Routing is one-to-one. If that router input/output is already consumed by another destination, the request is refused 6. SYSFW will not re-allocate an already-allocated resource without a reset 7.
    • Confirm the SBL actually carries the edited rm-cfg. A board-config/SBL mismatch is a known cause of this failure, because the flashed RM config assigns the router input to a different core than the application expects 8. Editing rm-cfg.yaml alone has no effect until rebuilt and reflashed.
    • R5FSS0-0 is not categorically barred from this router — the stock SDK config grants it outputs 0–7, and anything beyond that needs explicit reallocation 9.

    I cannot verify the type: 192 / host_id: 51 values in the rm-cfg entry against any retrieved source. Please confirm those against the SDK's resource-type and host-ID headers for the SDK version in use — if host_id names the wrong host (caller vs. ICSSG1 destination), the allocation exists but does not apply to this request.

    3. "Does rmIrqSetRaw bypass the rm-cfg check?" — No

    That inference does not hold. What the evidence supports:

    • MAIN_GPIOMUX routing is a resource-managed path: SYSFW validates the requested output against board-configured host ownership and rejects unallocated/conflicting requests, regardless of raw vs. abstracted API 3, 5.
    • TIMESYNC_INTRTR0 is a separate, dedicated time-sync event router (42 inputs / 41 outputs, 6-bit MUX_CNTL) 10, 11, distinct from GPIOMUX_INTRTR0 (54 outputs, 8-bit MUX_CNTL) 12, and the two feed different DMSS L2G interrupt-input ranges 13.

    So the asymmetry is a per-router resource-management policy difference, not a property of rmIrqSetRaw. The TIMESYNC route succeeding without an rm-cfg entry tells you nothing about GPIOMUX.

    Gap: no retrieved source states the SYSFW rule that exempts TIMESYNC outputs from RM allocation. I cannot give the authoritative reason.

    Also: a successful Sciclient_rmIrqSetRaw ack does not mean the interrupt will fire — the destination core's interrupt line must be registered and enabled separately. The cited GPIO case only worked after fixing that 3.

    4. The data abort on the direct register write

    Expected. MAIN_GPIOMUX interrupt-router outputs are configured only through SYSFW/TISCI; direct register writes are not a supported path 3. Reading PID succeeding while output-register writes abort is consistent with access being arbitrated outside the CBASS firewall region the customer inspected.

    Gap: the documentation I retrieved does not describe the firewall programming or write-protection mechanism for MAIN_GPIOMUX_INTROUTER0, so I cannot explain why ID34/region 8 behaves differently for this router vs. TIMESYNC and CMP event routers. That specific question needs a SYSFW/security-config answer.

    Recommended sequence

    1. Change raw src_index from 137 → 147.
    2. Confirm out_46 is the ICSSG1-connected output in the output map 4.
    3. Validate type and host_id in the rm-cfg entry against the SDK headers; the host must be the one SYSFW checks for this route.
    4. Rebuild and reflash the SBL so the modified rm-cfg is actually active, then retest.
    5. Separately register/enable the interrupt at the ICSSG1 destination.
    6. When changing mux control, disable the interrupt first and re-enable after, to avoid spurious asynchronous output toggles 14.

    Note one unresolved discrepancy worth checking in the TRM: one table lists GPIO1 outputs mapping into router inputs 99–131 15, while the GPIO1_GPIO_OUT_57 → IN_147 mapping comes from two other tables 1, 2. Confirm which table covers direct (non-banked) outputs before finalizing the index.

    Follow up: Would it help to pull the specific SDK board-config documentation for rm-cfg.yaml resource types and host IDs so the type: 192 / host_id: 51 entry can be validated directly?

    1. AM64x TRM — GPIO1_GPIO_OUT_57 to router input mapping
    2. AM64x TRM — MAIN_GPIOMUX_INTROUTER0 input interrupt table
    3. E2E: AM6442 — How to config the GPIO MUX interrupt router
    4. AM64x TRM — MAIN_GPIOMUX_INTROUTER0 output destinations
    5. E2E FAQ: AM64x — How to run MCU SDK GPIO interrupt example on Linux
    6. E2E FAQ: AM64x — Routing the same GPIO bank interrupts to different destination cores
    7. E2E: AM6442 — Triggering DMA for PRU IO data capture
    8. E2E FAQ: AM6442 — GPIO input interrupt Sciclient config failed in MCU+ SDK 6.0 above
    9. E2E: AM6442 — Sciclient_gpioIrqSet fails on R5FSS0-0
    10. AM64x TRM — TIMESYNC_INTRTR0 overview
    11. AM64x TRM — TIMESYNC router MUX_CNTL registers
    12. AM64x TRM — GPIOMUX router MUX_CNTL registers
    13. AM64x TRM — DMSS L2G interrupt input ranges
    14. AM64x TRM — Interrupt router programming guidance
    15. AM64x TRM — GPIO1 interrupts into router inputs 99–131
  • Yes that was a typo in the ticket but was correct in my code, I confirm that src_index was already 147.

    The problem was located in the rm-cfg file.

    For anyone that is facing problems with GPIOMUX routers, here are things to know:

    1- DMSC is checking the rm-cfg of the board, will not ACK the tisci command if the check fails.

    2- This DMSC check is done for the GPIOMUX router but not for TIMESYNC router, even when using a raw call.

    3- The raw call must have a req as follows:

    Flags: TISCI_MSG_VALUE_RM_DST_ID_VALID | TISCI_MSG_VALUE_RM_DST_HOST_IRQ_VALID | TISCI_MSG_VALUE_RM_SECONDARY_HOST_VALID

    Src_id: 3 (AM64X_DEV_MAIN_GPIOMUX_INTROUTER0), src_index: 0 to 199 (https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/interrupt_cfg.html#main-gpiomux-introuter0-interrupt-router-input-sources)

    Dst_id: 3 (AM64X_DEV_MAIN_GPIOMUX_INTROUTER0), dst_host_irq: 0 to 53 (https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/interrupt_cfg.html#main-gpiomux-introuter0-interrupt-router-output-destinations)

    ia_id = vint =0, global_event = 1, vint_status_bit_index =0, secondary_host = host id making this tisci call (36 for R5F0_0, https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/hosts.html)

    4- Lastly, the critical part: in rm-cfg, the order is critical for resources' entries to be recognized, they must be ordered by increasing type first, then by start_resource.

    Last question for TI:

    Is SYSFW setting up a FW rule that blocks all others cores from writing to zone 0xA00000->0xA00324?

    Thank you.

  • Thanks for the above detailed explanation. Looks like you are now able to set up the router configuration.

    the order is critical for resources' entries to be recognized, they must be ordered by increasing type first

    Can you please explain, what do you mean by above statement?

    Is SYSFW setting up a FW rule that blocks all others cores from writing to zone 0xA00000->0xA00324?

    I am routing your query to another team member to comment on firewall configuration.

    Regards,

    Tushar