I have a specific requirement where I nee to disable my device interrupt for specific period without affecting other interrupts(code running on ARM processor). ARM document pointed that all GIC registers (related to enable, disable and clear interrupts) of ARM are Banked registers, that is there is one per CPU Interface. Banked registers accessible from the designated CPU and controls that CPU's PPI and SGI interrupts only.
What does that mean? If I disable a specific interrupt by writing to GIC register, does that get disabled only on that core or all on cores?
There are two register sets with the GIC; a banked per CPU set and the distribution (also distributor) which is system global for the GIC. For the link above, the IrqEnSet0 is a per-CPU register which is banked (again) and handles the PPI and SGI interrupts to a CPU. The IrqEnSet1 is a list of global interrupts and these maybe disable. The distribution (also distributor) can also target certain interrupts to a CPU.
ARM has many different names for these registers and different versions of the GIC. The concepts are the same for all of them. There is a set of registers that are not banked per-CPU and these control things globally including disabling the interrupts system wide. Hopefully the reader is competent enough to find and read the specific controller documentation for their SOC.
What does that mean? If I disable a specific interrupt by writing to GIC register, does that get disabled only on that core or all on cores?
PPI - peripheral private interrupt. For example, a per-CPU timer in SMP systems.
SGI - software generated interrupt. Also known as IPI on other systems. This allows signaling from one CPU to another CPU. (IPI is inter-processor interrupt).
These interrupts only make sense for each and every CPU. However, hardware like Ethernet, SPI, Video, CAN bus, i2c, ADC, etc. are usually system global.
For the distributor registers, usually the global interrupts have a read/write enable/disable. The registers for the per-CPU are probably read-only in the distributor and indicate that the interrupt is present. The other set of registers (per-CPU) are the normal mechanism to enable/disable the interrupt per-CPU. Software should have an inter-lock (semaphore) when accessing the distributor as it is global to the system. Alternatively, only an elected or boot CPU would use the distributor. The per-CPU registers are banked so a core may perform a read-modify-write without worrying about race conditions.
Reference: ARM Generic Interrupt Controller - Architecture Specification, may require registration.
Related
I am working on an ARMv7 project, which has 2 cores.
According to ARM GICv2 spec. there are 16 PPIs for each core.
So my understanding is the PPI is local to each ARM core, and it should be signaled to and handled by the core.
According to ARM GICv2 spec, the PPI should have the same irq_num for all cores.
I could NOT figure out how is a PPI handled by each core.
Let me use localtimer as an example, each core has an local timer which can interrupt the connected core, in this case, how to install/register the software interrupt handler for that timer interrupt? Or there is a global interrupt handler for the interrupt targets to each core?
I found the answer to it.
As GICv2 spec. says, each PPI is private to each Core, and it is not impacted by ITARGETSRn register. Some GIC registers are banked, so each core has its own register to access.
As for the local timer example, each core should configure the same GIC registers to setup the timer interrupt, and the timer interrupt handler can be ran on each core when the PPI is triggered.
This is the local timer interrupt, which can be used as scheduling tick.
I was learning about interrupts and came here to see if someone can help me!
A) I understand that the interrupt is the electrical signal sent by some external hardware to the processor, via one of the input ports.
B) I understand that in some MCU's more than one input port are "attached" to only one interrupt.
Can exist an useful input port in a MCU that is not linked to any interrupt at all?
A) I understand that the interrupt is the electrical signal sent by
some external hardware to the processor, via one of the input ports.
That is surely one class of interrupt, sure, as long as you understand that 'external hardware to the processor' can mean 'internal to the controller chip' - many MCU have extensive integrated peripherals.
B) I understand that in some MCU's more than one input port are
"attached" to only one interrupt.
Yes - that is not uncommon. The intrrupt-handler then has to poll the port to find out which GPIO/whatever pin generated the interrupt.
Can exist an useful input port in a MCU that is not linked to any
interrupt at all?
Sure, especially on 'trivial' controllers that do not require high-performace IO and have no RTOS.
Even higher-performance MCU apps may poll for sundry reasons. One common example is reading keypads. The input rate is very low and the mechanical switches need to be debounced. Fastening every KB read line to an interrupt line may cause unwanted multiple interrupts. Such iputs are better polled, though even then, a timer interrupt often handles the polling.
The answer is probably "yes," but it depends on the microcontroller architecture. There's no guarantee that one vendor's MCU will behave the same as any other (with respect to interrupts, ports, or anything else). If you're tasked with learning a particular MCU, then learn it, live it.
You house may have only one doorbell button. But pretty much anyone can use it for whatever reason. UPS there is a package. neighbor kid to play with your kid. someone trying to sell something and so on. A processor is no different. To reduce latency newer designs may have multiple interrupt signals on the core so that the handler doesnt have to do as much if any work to figure out who caused the interrupt. Kind of like having ringtones for every person on your phone, so you can tell without looking who is calling. Vs. one ringtone for everyone and you have to look.
Do not confuse external gpio ports on the chip with interrupt lines, they are not. they are general purpose I/O. they might have a way to be used as interrupts or not, depends on the design of the chip. Again as with the doorbell on your house, there are many things, technically all of them are within the chip (microcontroller), that create interrupts. Because software has to setup handlers before it can...handle...interrupts, all sources of interrupts are disabled at first, and only the ones software enabled have the ability to actually reach the core and cause an interrupt. Logic in the chip. so you may have an interrupt signal tied to the uart receiver and you might enable that. You might have one for the tx buffer, when it is empty interrupt. but you have to enable those before the processor can get an interrupt. there is a small section of logic that does fire an interrupt every time one of those events occurs, but that signal is gated and cannot reach the core, blocked by logic you control.
You can have timers in the mcu, that interrupt you when they roll over or count to zero. But you have to not only setup the timer to do that with software, you also have to enable the interrupt from making it across the chip from the timer to the processor core.
And yes sometimes the gpio peripheral has a way to interrupt the processor as well. as with everything else you have to with software setup the peripheral and define what interrupts you want and you have to enable them across the chip.
There are more different ways of doing this than there are companies making chips as they dont always do it the same way across their product lines. But generally at a minimum there is an interrupt enable on the peripheral end, one or many depending on the peripheral and features, that you have to enable in order for that signal to leave that peripheral on its way to the core. And there is often an interrupt controller peripheral or something built into the core or near it that takes all the dozens or hundreds of individual interrupt connections in the chip and prioritizes them and orrs them into the one or few interrupt lines into the core. you generally have to also enable the corresponding interrupt that matches the signal coming out of your peripheral to reach the processor core. And then there is sometimes an interrupt enable in the core itself so that even if you have the peripheral enabled, the interrupt controller enabled for that one peripherals interrupt, you still cannot interrupt the processor unless the interrupt enable in the processor core is enabled. That is the simple case, it can get more complicated if there are more layers of interrupt controllers along the way. Well the simple case is when you have something like a cortex-m with dozens or hundreds of individual interrupt signals, still have interrupt enables on both ends and in the core, just easier to manage as you have dozens to hundreds of interrupt handlers instead of one mega handler for everything.
So dont confuse the pins on the chip as being interrupts, on older dedicated processors, like the 8088/86, sure that was the one interrupt pin. But general purpose I/O sometimes called GPIO sometimes called ports, are just a peripheral, they are just pins you can make go high or low, they are not there to be interrupts although there may be a feature in that peripheral for that (or maybe there isnt). And again interrupt signals go through logic gates and have to be enabled, by software, at a minimum on both ends of that signal, at the peripheral and at the interrupt controller.
In ARM architecture I have read that there are 3 kinds of interrupt :
PPI - Per processor interrupts
SPI - Shared processor interrupts
SGI - Software generated interrupts
I want to know what are these, and how they are different from each other ?
Software Generated Interrupt (SGI)
This interrupt is generated explicitly by software by writing to a dedicated distributor register, the Software Generated Interrupt Register. It is most commonly used for inter-core communication. SGIs can be targeted at all, or at a selected group of cores in the system. Interrupt numbers 0-15 are reserved for this. The software manages the exact interrupt number used for communication.
Private Peripheral Interrupt (PPI)
This interrupt is generated by a peripheral that is private to an individual core. Interrupt numbers 16-31 are reserved for this. PPIs identify interrupt sources private to the core, and are independent of the same source on another core, for example, per-core timer.
Shared Peripheral Interrupt (SPI)
This interrupt is generated by a peripheral that the Interrupt Controller can route to more than one core. Interrupt numbers 32-1020 are used for this. SPIs are used to signal interrupts from various peripherals accessible across the whole system.
You can read here
I am trying to add multiprocessor support for an embedded operating system (DNA-OS) on the Zynq platform in the ZedBoard.
The OS is actually flawlessly functional with CPU_0 alone. The OS architecture requires the implementation of a cpu_send_ipi function in order to activate multiprocessing support: Basically, this function would interrupt a processor and give him a new thread to process.
I looked for an IPI register in the ug585 (Technical Reference Manual for Zynq) but couldn't find any.
I tried digging further in the Cortex-A9 spec for an IPI register, and found out that software generated interrupts could be used as IPI.
After adding software interrupt support to my OS, the problem is that CPU_0 can interrupt itself, but cannot interrupt CPU_1 !
PS: for my OS to handle SGIs, I used the register spec from the ug585 in page 1486:
So is there any other special configuration to permit CPUs to interrupt each others? or any other way to implement IPI ?
Regards,
Your reference documentation is a form of the GIC (global interrupt controller). The Cortex-A9 MP cores include an integrated GIC controller. Each CPU includes an Interrupt interface. As well, there is a system wide distributor. In order to receive the IPI (also known as SGI or software generate interrupt), you need to enable the CPU interface to receive the SGI interrupts on the 2nd CPU. This entails several steps,
Configuring the GIC interrupt interface registers on CPU2.
Setting the CP15 vector table for CPU2.
Enabling the CPSR I-bit on CPU2
Possibly setting up some banked PPI distributor registers. note1
Note1: While most distributor registers are system global, some are banked per CPU as well. For instance, see section 3.3.8. PPI Status Register in the Cortex-A9 MPcore TRM. I don't see any from a cursory investigation, but I would not rule it out.
Testing that an unused SPI (shared peripheral interrupt) works by handling the vector on CPU2 by setting the GIC distributor GICD_ISPEND register on the CPU1. This should verify that you have steps 2 and 3 covered. You may also need to set the type to ensure that they are interrupts and not FIQ; especially if you have security support. You need to use the GICD_ITARGETSR register to include CPU2.
GIC reference list
ARM Generic GIC document - registration needed, GICv1 (ignore GICv2 info).
ARM Cortex-A9 MPcore TRM - chapter 3, for specific info.
PL390 TRM - it is not spelled out anywhere, but I think this is the integrated GIC. It maybe worth looking at if you use more esoteric features.
Especially useful in the Appendix B of the Generic GIC manual. For some reason, ARM likes to keep changing the register names in each and every document they publish.
I am working on a project where i am trying to figure out how an interrupt is processed in the Global interrupt controller for a ARM architecture. I am working with pl390 interrupt controller. I see there is a line which is mentioned as legacy interrupts which bypasses the distributor logic. It is given that 2 interrupts can be programmed as a legacy interrupt. Can any one help with some explanation of what exactly is a legacy interrupt?. I trying searching online without any luck.
Legacy interrupts are the two interrupts that were in ARM before GIC arrived: nIRQ - normal interrupt request, and fIRQ - fast interrupt request.
Since legacy interrupts were made for single-core processors, and they don't support multi-core processors internally, the reason they bypass the distributor logic should be rather clear - the legacy interrupts are hardwired into one of the cores.
In short - it allows the CPU to work in backwards compatibility with older ARM specification. For example, a four-core ARM CPU will have 4 nIRQs and 4 fIRQs, separate for each of the cores. When you have an old piece of ARM-compatible hardware (which doesn't support GIC), you connect it to one of the core's nIRQ/fIRQ just as if you connected it to an old single-core CPU, and it will always execute on that one core.
More information can be found here - http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0407e/CCHDBEBE.html