I understand that at 'and' instruction it is actually preserving mode bits
as offset in the table immediately following this code. But why we are using
such a trick? Are we getting some kind of optimization by doing so?

On Sat, Apr 26, 2008 at 4:23 PM, sahlot arvind <[EMAIL PROTECTED]> wrote:

> In order to understand the code, at the moment I ignored 'stubs_offset'.
>
> >/*
> > * Interrupt dispatcher
>   >*/
>   >     vector_stub     irq, IRQ_MODE, 4
>
> After expansion it will look some thing like this -
>
> *vector_irq:
>                 ...
>                 blah - blah
>                 ...
>        @ the branch table must immediately follow this code
>         and     lr, lr, #0x0f
>         mov     r0, sp
>         ldr     lr, [pc, lr, lsl #2]
>         movs    pc, lr          @ branch to handler in SVC mode
>        .long   __irq_invalid                 @  1  (FIQ_26 / FIQ_32)
>   .    .long   __irq_invalid                @  2  (IRQ_26 / IRQ_32)
>        .long   __irq_svc                   @  3  (SVC_26 / SVC_32)
>        .long   __irq_invalid                   @  4
>        .long   __irq_invalid                   @  5
>        .long   __irq_invalid                   @  6
>        .long   __irq_invalid                   @  7
>        .long   __irq_invalid                   @  8
>        .long   __irq_invalid                   @  9
>        .long   __irq_invalid                   @  a
>        .long   __irq_invalid                   @  b
>        .long   __irq_invalid                   @  c
>        .long   __irq_invalid                   @  d
>        .long   __irq_invalid                   @  e
>        .long   __irq_invalid                   @  f*
>
> I guess that the instruction in the above code -
> *    movs    pc, lr          @ branch to handler in SVC mode
> *will jump to address specified by *
>    .long   __irq_svc                   @  3  (SVC_26 / SVC_32)*
>
> Assuming I am right then the instruction -
>
> ldr     lr, [pc, lr, lsl #2]
>
> will set 'lr' to the address of '__Irq_svc'. But I am unable to understand
> how come this instruction is setting up lr to point to __irq_svc?
> In the above code while executing 'and' instruction 'lr' contains the
> value of 'spsr' and last four bits are mode bits then this 'and' instruction
> is preserving those 4 bits (mode bits). But why do we need those bits and in
> 'ldr' why we are doing left shift by 2? Cannot we simply add 16 (since there
> are one instruction and 3 handler addresses after 'ldr' instruction) to 'pc'
> and load it into 'lr' so that 'lr' starts pointing to __irq_svc, which is 4
> words down the 'ldr' instruction?
> And one more question why do we have 16 handlers in each exception stub?
> why not just 1 (e.g. __irq_svc) or 2 (__irq_usr and __irq_svc)? and what is
> use of __irq_usr?
>
> I am sorry I have put lot of questions in this email. But answers to them
> would really help me in understanding the code.
>
> Thanks in advance.
> - A Sahlot
>
> On Sat, Apr 26, 2008 at 11:37 AM, sahlot arvind <[EMAIL PROTECTED]> wrote:
>
> > Thanks Russell. I will re-try and get back in case dont understand.
> >
> > - A
> >
> > On Sat, Apr 26, 2008 at 2:09 AM, Russell King - ARM Linux <
> > [EMAIL PROTECTED]> wrote:
> >
> > >  On Fri, Apr 25, 2008 at 02:31:20PM +0530, sahlot arvind wrote:
> > > > Guys,
> > > >
> > > > I am trying to understand the flow of control when an interrupt
> > > comes.
> > > > I am reading linux-2.6.24 src code and looking at
> > > > arch/arm/kernel/entry-armv.S.
> > > > At the bottom of this file I see the vector table as below -
> > > >
> > > > __vectors_start:
> > > >     swi SYS_ERROR0
> > > >     b   vector_und + stubs_offset
> > > >     ldr pc, .LCvswi + stubs_offset
> > > >     b   vector_pabt + stubs_offset
> > > >     b   vector_dabt + stubs_offset
> > > >     b   vector_addrexcptn + stubs_offset
> > > >     b   vector_irq + stubs_offset
> > > >     b   vector_fiq + stubs_offset
> > > >
> > > >     .globl  __vectors_end
> > > >
> > > >
> > > > Here is not 'stubs_offset' a constant? and after seeing an IRQ where
> > > are we
> > > > branching by doing ' b   vector_irq + stubs_offset'  and what is the
> > > flow of
> > > > control???
> > >
> > > It's all rather mystical if you don't understand the ARM instruction
> > > set.
> > >
> > > 1. 'b' is a branch instruction.  All branches are relative to the
> > >   current PC.
> > >
> > > 2. the code is not executed in the location where you find it in
> > >   the kernel.  It is copied to other locations in memory.  Other
> > >   code (between __stubs_start and __stubs_end) is copied to 512
> > >   bytes above the start of the vectors, and these branch instructions
> > >   branch to that other code.
> > >
> > > 3. __stubs_offset is just a correction factor to convert the branches
> > >   to point at the correct _relative_ position when they're copied to
> > >   their proper location in memory.
> > >
> > > The simple way to _read_ the code is to ignore the 'stubs_offset' and
> > > just
> > > follow the branch instruction to vector_irq:
> > >
> > > /*
> > >  * Interrupt dispatcher
> > >  */
> > >        vector_stub     irq, IRQ_MODE, 4
> > >
> > > and then look at what vector_stub expands to.
> > >
> >
> >
> >
> > --
> > http://linuxexplained.blogspot.com
>
>
>
>
> --
> http://linuxexplained.blogspot.com




-- 
http://linuxexplained.blogspot.com

Reply via email to