Hi,
Working on https://github.com/thesofproject/sof/pull/1053 I'm making sure all the DSP cores see the same data, which on Xtensa seems to require manual cache synchronisation. This is a painful task, it's actually even only practically possible because there aren't many objects in SOF that can be accessed by different cores. However, with that PR interrupt descriptors will also become accessible by multiple cores.
On Sue Creek there are two kinds of cascading interrupt controllers: internal "level2" - "level5" and a DesignWare interrupt controller IP, used by several peripherals, uncliding the UART. With the addition of manual cache synchronisation UART interrupts stopped working. Debugging showed, that DW INTC interrupt descriptors lose their updates when other descriptors have their cache invalidated. And those descriptors aren't even immediately close to each other in RAM. Roughly the following is happening:
dw_intc->irq = new_irq; list_for_item(list, descriptors) { desc = container_of(list, struct irq_desc, list); dcache_invalidate_region(desc, sizeof(*desc));
at which point dw_intc->irq loses its new_irq value and restores the initial -EINVAL value. If I either remove the invalidation line above or add a writeback for dw_intc between the first two lines, the problem goes away.
Therefore questions:
1. am I using cache invalidation wrongly? 2. if the invalidated memory region isn't cache-line aligned, what happens then? Are all full lines invalidated, thus potentially erasing data? But even if this were handled wrongly, it wouldn't cause this problem, because those descriptors aren't adjacent in RAM. 3. is that a software or a hardware bug? 4. how to fix?
Thanks Guennadi