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
