Sebastian Huber commented on a discussion on 
testsuites/validation/tc-score-isr.c: 
https://gitlab.rtems.org/rtems/rtos/rtems/-/merge_requests/1452#note_158216

 > -  register uintptr_t sp __asm__( "1" );
 > -
 >    if ( interrupted_stack_at_multitasking_start == 0 ) {
 > -    interrupted_stack_at_multitasking_start = sp;
 > +    const Per_CPU_Control *cpu_self;
 > +    const uintptr_t       *frame;
 > +
 > +    /*
 > +     * The dispatch runs on the interrupt stack.  The switch to that stack
 > +     * stores the stack pointer of the interrupted context at the begin of 
 > the
 > +     * frame at the top of the interrupt stack.
 > +     */
 > +    cpu_self = _Per_CPU_Get();
 > +    frame = (const uintptr_t *) ( (uintptr_t) 
 > cpu_self->interrupt_stack_high -
 > +      CPU_INTERRUPT_FRAME_SIZE );
 > +    interrupted_stack_at_multitasking_start = *frame;

Neither r1 nor r3.  The word at offset 0 of this frame is not a saved
register.  The interrupt path builds two frames and only one of them holds
saved registers.

`_interrupt_handler.S` builds the first frame on the stack of the
interrupted context.  It saves r3 to r18 and the MSR.  The
`MICROBLAZE_INTERRUPT_FRAME_*` offsets describe this frame.

`_ISR_Handler` then tests whether the stack pointer is inside the interrupt
stack.  If it is not, `switch_to_interrupt_stack` builds a second frame at
the top of the interrupt stack:

    switch_to_interrupt_stack:
      add r4, r0, r1                           /* base of the first frame */
      lwi r1, r0, _Per_CPU_Information + 4     /* interrupt_stack_high */
      addik r1, r1, -(CPU_INTERRUPT_FRAME_SIZE)
      swi r4, r1, 0

The return path reads the same word back to leave the interrupt stack:

      lwi r1, r1, 0

The second frame reuses the size of the first frame.  It does not reuse the
layout.  Its only member is the stack pointer of the interrupted context at
offset 0.  That is the word the test reads.  The saved r3 sits in the first
frame at a different address on the interrupted stack.

The value the test gets is the base of the first frame, that is the
interrupted stack pointer minus 56.  The test checks membership in the
initial stack area of the thread, so the offset makes no difference.

The collision of `MICROBLAZE_INTERRUPT_FRAME_R3` with offset 0 is what makes
this hard to read.  I can add a name for the offset in `cpuimpl.h`:

    /*
     * The frame at the top of the interrupt stack stores the stack pointer
     * of the interrupted context at this offset.
     */
    #define MICROBLAZE_INTERRUPT_FRAME_SP 0

Then `cpu_asm.S` and this test use the name instead of a bare 0.  Tell me if
you want that and I add it as a preparation commit.

-- 
View it on GitLab: 
https://gitlab.rtems.org/rtems/rtos/rtems/-/merge_requests/1452#note_158216
You're receiving this email because of your account on gitlab.rtems.org. 
Unsubscribe from this thread: 
https://gitlab.rtems.org/-/sent_notifications/5-d4tadc3q9fyw9n12tsewhth7f-1d/unsubscribe
 | Manage all notifications: https://gitlab.rtems.org/-/profile/notifications | 
Help: https://gitlab.rtems.org/help


_______________________________________________
bugs mailing list
[email protected]
http://lists.rtems.org/mailman/listinfo/bugs

Reply via email to