<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Aug 1, 2018 at 10:11 AM, Gedare Bloom <span dir="ltr"><<a href="mailto:gedare@rtems.org" target="_blank">gedare@rtems.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On Wed, Aug 1, 2018 at 9:15 AM, Amaan Cheval <<a href="mailto:amaan.cheval@gmail.com">amaan.cheval@gmail.com</a>> wrote:<br>
> That's definitely very illuminating, thank you so much for all the details!<br>
><br>
> A few more questions that have arisen for me. Feel free to skip over<br>
> them (I'll likely figure them out given enough time, so I'm only<br>
> asking in case any of them are obvious to anyone):<br>
><br>
> - The i386 doesn't use CPU_Interrupt_frame at all. It seems like it<br>
> stores some of the data onto the stack?<br>
><br>
</span>the interrupt frame structure was introduced during 4.11 development.<br>
probably i386 never got updated to use a struct to encapsulate the<br>
interrupt frame. the interrupt frame should contain the registers that<br>
are preserved by the interrupt entry code I believe.<br></blockquote><div><br></div><div>+1 </div><div><br></div><div>Historically, there was no structure to represent the set of </div><div>registers and information saved on interrupt entry. Over time</div><div>this has been added. </div><div><br></div><div>i386 also is missing the SMP synchronization check in the<br></div><div>middle of the context which ensures it is safe for a thread to</div><div>be migrated.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class=""><br>
> - There used to be defines in cpu.h regarding hardware/software based<br>
> interrupt stacks, and how they'd be setup, which were made<br>
> superfluous[1] - I'm not quite sure how these are meant to work - I<br>
> see references to "stack high" and "stack low" and I'm not quite sure<br>
> what the code is referencing when using those.<br>
><br>
<br>
</span>a hardware interrupt stack is one that the hardware switches to during<br>
an interrupt. i think m68k has such.<br>
<br>
most interrupt stacks in RTEMS are software-managed, meaning that<br>
RTEMS explicitly switches the stack region off the task stack and to<br>
an interrupt stack region.<br>
<br>
some stacks start high and grow down, and some stacks start low and<br>
grow up. maybe this is what the "stack high" and "stack low" you<br>
mention are in relation to?<br></blockquote><div><br></div><div>They are used to denote the top and bottom of the memory reserved</div><div>for the interrupt stack. One important use is in cpukit/libmisc/stackchk/check.c</div><div>to report on usage.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class=""><br>
> - c/src/lib/libbsp/no_cpu/no_<wbr>bsp/Makefile.am doesn't include<br>
> <a href="http://irq-sources.am" rel="noreferrer" target="_blank">irq-sources.am</a>, by the way (this is part of why I used to think a lot<br>
> of what your email mentioned was unnecessary, until you...ahem,<br>
> pre-empted that line of thought and helped clarify it :P). Should I<br>
> add a ticket to update the no_bsp code to be more in line with current<br>
> use?<br>
><br>
</span>Sure. I don't know that anyone is in particular maintaining<br>
no_cpu/no_bsp since we can't compile it, it is basically best effort<br>
stuff that sometimes we miss updating.<br></blockquote><div><br></div><div>+1 </div><div><br></div><div>Also there are variations based on simple vectored and PIC vectored</div><div>architectures.</div><div><br></div><div>The architecture is responsible for the managing the minimal actions</div><div>based on what the CPU does for an interrupt/exception. Logically</div><div>a PIC is part of the BSP even if it comes integrated with the CPU as</div><div>is common on x86 and SoCs. The PIC could fairly easily change </div><div>and the architecture is harder to change. </div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class=""><br>
> - My understanding of _ISR_Handler is that it'll be the handler for<br>
> _all_ interrupt vectors by default - it'll then dispatch interrupts to<br>
> user-handlers (or internal handlers, for the timer, for eg.). Is that<br>
> right? (I don't quite understand its interaction with the RTEMS<br>
> interrupt manager yet, but irq-generic's "bsp_interrupt_handler_table"<br>
> seems to be the RTEMS equivalent to the processor-specific vector<br>
> table, and "bsp_interrupt_handler_<wbr>dispatch" seems to call the actual<br>
> handler within that table as appropriate. Accurate? (I just haven't<br>
> found how that table actually gets its handlers setup besides during<br>
> initialization, since rtems_interrupt_catch just calls<br>
> _CPU_install_vector, which updates the processor vector table, not the<br>
> RTEMS interrupt manager vector table.)<br>
><br>
<br>
</span>You have discovered a couple of different but related interrupt<br>
processing code bases. I can see why you get confused.<br>
<br>
Basically, a CPU port should support two kinds of interrupts that may<br>
be installed, "RTEMS" and "Raw" interrupts. The "Raw" interrupts are<br>
installed directly in the processor's vector table. For processors<br>
that use simple vectored interrupts, the "RTEMS" interrupts install a<br>
call to the _ISR_Handler() function in the processor's vector table,<br>
and will put the user's isr function pointer in the<br>
_ISR_Vector_table(), which is the RTEMS Interrupt Manager's vector<br>
table.<br>
<br>
I'm not really familiar with the processors that use a different model<br>
for interrupt handling besides simple vectored. Probably, you will<br>
have to study one of them.<br>
<br>
This irq-generic bsp_interrupt_* code is used by the "IRQ Server" that<br>
builds from the CPU port capabilities to allow for some advanced<br>
features like chaining multiple isrs from the same source. I don't<br>
think you want to be focusing on those right now, but I could be<br>
mistaken. I haven't spent much time looking at the IRQ Server<br>
codebase.<br></blockquote><div><br></div><div>For the most part, the bsp_interrupt_* code is hung off of one </div><div>(or more) of the simple vectored sources. On many architectures,</div><div>you have very few "CPU vectors" and the bsp_interrupt_* is</div><div>the secondary layer managing the PIC. Notice that it is all </div><div>in C and thus isn't first level processing. And it doesn't deal</div><div>with RTEMS critical section, interrupt entry/exit, and dispatching..</div><div><br></div><div>For example, in its original form, the PowerPC didn't have many</div><div>"exceptions" (e.g. CPU vectors) at all. In fact, there was a single</div><div>External Exception which was always tied to a board dependent</div><div>PIC. The first level processing of PPC exceptions is in assembly</div><div>and deals with what I pointed you to in various _ISR_Handler's.</div><div>The External Exception handler now process bsp_interrupt_*.</div><div>The gen5200 BSP irq.c file has a bsp_interrupt_* implementation</div><div>which registers for two "exceptions" which both go to </div><div>C_dispatch_irq_handler() which reads the PIC, determines</div><div>the source(s), and dispatches (via bsp_interrupt_handler_dispatch()</div><div>the registered IRQ. </div><div><br></div><div>If you think of this as two levels of processing, it should help.</div><div><br></div><div>The two levels of processing is for RTEMS interrupts which can</div><div>unblock threads, etc. The first level ensures that locking and</div><div>dispatching is handled.</div><div><br></div><div>As Gedare stated, there are also Raw interrupts which ignore</div><div>RTEMS and can't use RTEMS services. These should never</div><div>be anything but the highest priority interrupt in a system. The</div><div>RTEMS first level processing can switch to a dedicated </div><div>interrupt stack and mixing RTEMS and Raw IRQs can</div><div>screw up the stack handling as well as the interrupt nesting</div><div>count.</div><div><br></div><div>--joel</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class="HOEnZb"><font color="#888888"><br>
Gedare<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
> - My understanding of the interaction between RTEMS' interrupt manager<br>
> (i.e. support for nested interrupts and thread dispatch once an<br>
> interrupt ends) and the BSP's processor-specific interrupt manager<br>
> (code to use the APIC and IDT in my case) is that they're tied<br>
> together through the use of irq-generic.c's "bsp_interrupt_initialize"<br>
> - is that right? (m68k never seems to call it, though, so perhaps<br>
> not?)<br>
><br>
> Sorry about the rambling! To reiterate, I'll likely figure it out<br>
> given enough time, so if the answers aren't at the top of your head, I<br>
> can figure it out without wasting your time :)<br>
><br>
> [1] <a href="https://devel.rtems.org/ticket/3459#comment:11" rel="noreferrer" target="_blank">https://devel.rtems.org/<wbr>ticket/3459#comment:11</a><br>
><br>
> On Wed, Aug 1, 2018 at 3:18 AM, Joel Sherrill <<a href="mailto:joel@rtems.org">joel@rtems.org</a>> wrote:<br>
>><br>
>><br>
>> On Tue, Jul 31, 2018 at 3:05 PM, Amaan Cheval <<a href="mailto:amaan.cheval@gmail.com">amaan.cheval@gmail.com</a>><br>
>> wrote:<br>
>>><br>
>>> Hm, I'm not sure what to look for in the other ports specifically, really.<br>
>>> The BSP porting documentation doesn't have a section on interrupts, so I'm<br>
>>> doing this on more of an "as it comes up" basis.<br>
>>><br>
>>> What I've got right now (the interrupt handlers in C) are what I need for<br>
>>> calibrating the APIC timer (through the PIT) - so simply hooking IRQ0 (for<br>
>>> the timer) and IRQ7 (spurious vector), since those are needed for the timer<br>
>>> work to continue.<br>
>>><br>
>>> What constitutes as a requirement for basic interrupt support?<br>
>><br>
>><br>
>> There used to be a generic porting guide. I can see that this particular<br>
>> section<br>
>> has bit rotted some but the interrupt dispatching section. Some of this<br>
>> will have evolved to support SMP and fine grained locking but the<br>
>> pseudo-code<br>
>> here will give you a push toward the right line of thinking:<br>
>><br>
>> <a href="https://docs.rtems.org/releases/rtemsdocs-4.10.2/share/rtems/html/porting/porting00034.html" rel="noreferrer" target="_blank">https://docs.rtems.org/<wbr>releases/rtemsdocs-4.10.2/<wbr>share/rtems/html/porting/<wbr>porting00034.html</a><br>
>><br>
>> The idea is that you need to ensure RTEMS knows it is inside an interrupt<br>
>> and the current locking scheme (old was dispatching, new is ...) is honored.<br>
>><br>
>> The ARM and PowerPC (plus RISCV) are good ports to look at for how SMP<br>
>> plays into this. But the CPU supplement is thin for their interrupt<br>
>> processing.<br>
>><br>
>><br>
>> This is the CPU Architecture supplement section for the m68k. This is a<br>
>> relatively simple<br>
>> architecture to describe. There is also a section for the i386 which reads<br>
>> similarly.<br>
>><br>
>> <a href="https://docs.rtems.org/branches/master/cpu-supplement/m68xxx_and_coldfire.html#interrupt-processing" rel="noreferrer" target="_blank">https://docs.rtems.org/<wbr>branches/master/cpu-<wbr>supplement/m68xxx_and_<wbr>coldfire.html#interrupt-<wbr>processing</a><br>
>><br>
>> Personally, I find the m68k a fairly easy processor to read assembly in.<br>
>> Look at cpukit/score/cpu/m68k/cpu_asm.<wbr>S and _ISR_Handler to see what<br>
>> is done there w/o SMP. On the m68k _ISR_Handler is directly put into the<br>
>> vector table. But this isn't the most similar example for you.<br>
>><br>
>> For the i386 (better example), it is in bsps/i386/shared/irq/irq_asm.S with<br>
>> the<br>
>> same name. There _ISR_Handler is installed via the DISTINCT_INTERRUPT_ENTRY<br>
>> macros at the bottom of the file where some prologue jumps to the common<br>
>> _ISR_Handler and then the actions are similar. Usually _ISR_Handler type of<br>
>> code ends up invoking a PIC decode method in normal C without an<br>
>> interrupt attribute.<br>
>><br>
>> Long and multi-architecture answer but maybe that makes sense. The goal<br>
>> in ticker.exe is to take a number of tick interrupts which don't schedule<br>
>> and<br>
>> then take one that does -- it schedules a preemption of the idle thread.<br>
>><br>
>> Hope this helps.<br>
>><br>
>> --joel<br>
>><br>
>><br>
>><br>
>>><br>
>>><br>
>>> On Wed, Aug 1, 2018, 1:29 AM Joel Sherrill <<a href="mailto:joel@rtems.org">joel@rtems.org</a>> wrote:<br>
>>>><br>
>>>><br>
>>>><br>
>>>> On Tue, Jul 31, 2018 at 2:52 PM, Amaan Cheval <<a href="mailto:amaan.cheval@gmail.com">amaan.cheval@gmail.com</a>><br>
>>>> wrote:<br>
>>>>><br>
>>>>> Hi Chris!<br>
>>>>><br>
>>>>> I currently have code like this in<br>
>>>>> c/src/lib/libbsp/x86_64/amd64/<wbr>Makefile.am:<br>
>>>>><br>
>>>>> librtemsbsp_a_SOURCES +=<br>
>>>>> ../../../../../../bsps/x86_64/<wbr>amd64/interrupts/handlers.c<br>
>>>>> # XXX: Needed to use GCC "interrupt" attribute directives - can we<br>
>>>>> pass these<br>
>>>>> # flags only for the handlers.c source file (compile to an object<br>
>>>>> file first and<br>
>>>>> # then link with the rest for librtemsbsp.a?)<br>
>>>>> librtemsbsp_a_CFLAGS = -mgeneral-regs-only<br>
>>>>><br>
>>>>> The CFLAGS arg is required to allow us to use<br>
>>>>> "__attribute__((interrupt))" to setup interrupt handlers in C. (See<br>
>>>>> [1] and ctrl+f "interrupt" for more.)<br>
>>>>><br>
>>>>> Is there a way to not force the CFLAGS for _all_ of librtemsbsp, but<br>
>>>>> to limit it only to handlers.c?<br>
>>>>><br>
>>>>> If not, is the above code something that would be acceptable to have<br>
>>>>> upstream?<br>
>>>>><br>
>>>>> [1]<br>
>>>>> <a href="https://gcc.gnu.org/onlinedocs/gcc/x86-Function-Attributes.html#x86-Function-Attributes" rel="noreferrer" target="_blank">https://gcc.gnu.org/<wbr>onlinedocs/gcc/x86-Function-<wbr>Attributes.html#x86-Function-<wbr>Attributes</a><br>
>>>><br>
>>>><br>
>>>> Are we basically talking about the outermost layer of your interrupt<br>
>>>> dispatching?<br>
>>>><br>
>>>><br>
>>>> Have you looked at the basic approach taken by the other ports? They end<br>
>>>> up switching the stack pointer to a dedicated stack on the outermost<br>
>>>> interrupt<br>
>>>> and, if a context switch/dispatch is needed, arrange for the interrupted<br>
>>>> task to call _Thread_Dispatch.But tinker with its stack so some registers<br>
>>>> are saved and it looks like it made the call itself.<br>
>>>><br>
>>>> If you can do it in C, I am ok with an attribute. I just don't think you<br>
>>>> can pull off all the stack and return to dispatch magic that way.<br>
>>>><br>
>>>> --joel<br>
>>>><br>
>><br>
</div></div></blockquote></div><br></div></div>