This is a very technical question. I am asking this here because I have spent too much time already trying to figure this out myself; please, bare with me.
I am doing some bare metal programming on the Galileo.
So far I have done some very basic initialization; basically, I am running my setup code in flat 32 mode following the code in Flat32.asm file provided by Intel for the Galileo. All code is running in ESRAM; no main RAM initialization yet.
- What I want to do: pass an interrupt from a PCIe card attached to the Galileo to the CPU and execute an ISR.
- Rationale: I am testing interrupt delivery so I can have some processes running and interrupting the execution flow before setting up main RAM. The PCIe peripherals will be requiring attention before main RAM memory is set up.
- What I have done to enable an interrupt to be passed from a PCIe board on the Galileo PCIe physical port to the CPU:
1.) Basic initialization of the PCI Root Ports (Manual enumeration, memory routing, and setup of the root port). I can read and write to the PCIe function registers via MMIO writes and set up the peripherals including the generation of interrupts in the peripherals of the PCIe card attached to the Galileo.
2.) Initialize IDTR.
3.) Set up the ISR's addresses in each ISR vector within the IDTRs constraints.
4.) Set up the 8259 PICs.
5.) Route the interrupts: PCIe board (INTA# ) -> Root Port 0 (Passes INTA# upstream) -> IRQAGENT1 (INTA# -> PIRQE) -> PIRQE Routing Control (PIRQE -> IRQ3) -> 8259 (IRQ3). Basically, I routed the INTA# interrupt from the PCIe add on card to one of the pins in the 8259 PICs (The primary PIC in this case.)
6.) Enable interrupts via IF.
The Problem: Reading the IRR register in the PICs after issuing an interrupt on one of the peripherals in the PCIe card returns a value: a 1 (high) on the bit corresponding to IRQ3. This tells me that the routing is working and that the interrupt is having an effect on the input pins of the 8259 PICs. However, the ISR remains 0x00 and there is no jump to any of the ISRs break points.
- This makes me think that the CPU is not acknowledging the reception of interrupts or that I am not enabling INTR pin correctly. My understanding is that I should not need to do anything with INTR since it is, by default, directly routed to the CPU (OR'ed to the RMU according to the datasheet [HMISC2 register]). There is no other place I can find a reference to the INTR pin, so I assume I don't have to do any routing to this pin or enabling it. Maybe there is something else I need to do?
- Am I missing anything in terms of Maskable interrupt configuration?
- Do I need to route INTR or enable it somehow?
- Are there some specific steps that will allow the INTR to interrupt the CPU in addition to the steps described here?
- Do I need to setup the PCIe root port in a specific manner? Since the interrupt is being passed to the PICs this seems not to be the case; moreover, the datasheet states that endpoint interrupts will be forwarded by the root port.
- Should I contact support?
Thank you beforehand for any insight you may be able to provide me with.
Thank you for contacting us and for providing a detailed description of your issue. As you mentioned, there are a lot of details involved in your case and the question is very specific, that's why I assume you've already seen the Quark documents that might be relevant for your configuration. I looked at some of those documents and in the ones I found information related to interrupts and PCIe was in the datasheet and PDG. If you haven't seen them yet, go to https://www-ssl.intel.com/content/www/us/en/embedded/products/quark/x1000/documentation.html https://www-ssl.intel.com/content/www/us/en/embedded/products/quark/x1000/documentation.html .
In the meantime we'll try to investigate a bit further about this and hope to find something useful.
Thank you for your understanding.
Thank you for helping on the resolution of this issue.
I have checked those documents. I have not found any additional useful information in them. In addition, to be able to start the PCIe Root Ports, I had to follow the Quark UEFI Firmware Writer's Guide; in it, the process of taking the Root Port out of reset and some basic initialization is detailed as well as the routing of interrupts.
- As mentioned, the interruption shows in the PIC 8259 PIC IRR register (by polling) which means the PICs are, in fact, detecting the interrupt, but the CPU seems to ignore it or the PICs are not passing the interrupt via INTR for some reason. PICs are set to level sensitive (since PIRQx# lines are inverted by the SoC according to the datasheet and this is the actual recommendation.) Nevertheless, the PIC's ISR shows 0 at any time.
- Now, here is another detail that may prove useful, I have initialized most of the Legacy Bridge's PCI configuration registers at this point; I didn't initialize the GPE0BLK, nor did I initialize the WDTBA. WDT is not needed at this point and it seemed to me that GPE is not necessary just yet since I will not be using SCI or SMI until later. Does GPE0BLK has any influence on the propagation of the INTR signal? I don't see anything specific about INTR on GPE0BLK.
Thank you again for any insight you may be able to provide me with.
Thank you for your patience.
We open source both the UEFI boot loader and Yocto project Linux BSP. UEFI code can be used as a starting point to learn how to initialize the Quark X1000, and from there you would be able to utilize bare-metal programming. After further reviewing your case, I'm afraid that providing guidance or assistance with bare-metal programming on Quark X1000 goes beyond the scope of our support.
We appreciate your understanding.
My organisation, Ircona (www.ircona.com), has been developing hardware and BIOS solutions and consultancy services for Intel based processors for over 15 years and have been working with the Quark processor family since its launch. Our team of BIOS engineers would be more than capabile of assisting you to resolve the issues you are seeing with your code.