Friday, 22 February 2013

The journey through Armenia

Armenia

It is the first Christian state in the world. In the 4th century, the kingdom of Armenia became the first nation to adopt Christianity as a state religion. Located at the crossroads of Western Asia and Eastern Europe, it is bordered by Turkey to the west, Georgia to the north, and Azerbaijan to the east, and Iran to the south. Its position between Europe and Asia is unique.

Armenia was conquered or invaded by many countries throughout the history, because it was never strong enough to defend itself.
Coming from Iran, i took a shared taxi towards Goris. The van traversed the windy mountainous road.

It is 53km to Goris, 285 km to Yerevan (the capital city).

This is the shared van that i took from the Iranian-Armenian border to Armenia proper.
One Iranian guy from the shared van. Yes, Iranians go on binge drinking (and all kinds of vice activities) once they are in Armenia. Armenia is like Vegas to them. 
Goris

To see some of the nicest samples of historical urban architecture in Armenia, go to Goris. It is the second largest city in southern Armenia.


Arriving at the city square of Goris

A quiet street and rows of old houses in Goris

The Saint Gregory Cathedral is the biggest one of its kind in Goris.

One example of typical Soviet-style apartment in Goris

The next day, i went around the area. It is a mountainous region.


The car drove around the road that wraps itself along the mountain.


 
The Tatev Monastery, it is a 9th century Armenian monastery located in south eastern Armenia. In the 14th and 15th century, it hosted the medieval Armenian university. It is a fortified monastery; and three churches, a library, mausoleum are located within the perimeter of the monastery. 

 
The Tatev Monastery from a distance


Ceremonial session was taking place in the church.

This is me at the Tatev monastery.



I took a shared taxi to Yerevan. The passengers on the taxi were two Armenian aunties with one young boy. They destination was a small village of Malishka, mid way between Yerevan and Goris. When they reached their house, the taxi driver and i were invited in, to drink freshly brewed coffee and eat the grapes, peaches, and watermelons. Their house is a single story house, nothing fancy and it is warm.


















The Armenian boy in the taxi

The rugged scenery of the countryside around the house.


The Ararat Mountain can be seen along the road. Supposedly, Noah's ark landed on the mountains of Ararat. Ararat mountain is very important in Armenian culture. The mountain is now located in Turkey.

In the morning, people go to an observatory hill to see the Ararat Mountain.


The Garni temple, it was first constructed in the year 115 (1900 years ago), and reconstructed many times. It was built in Greco-Roman style.


The monastery that is partially carved out of the mountain, the monastery of Geghard, a UNESCO world heritage site. The monastery was founded in the 4th century by Gregory the Illuminator.


A function room of the Geghard monastery, carved out from stone.


In the main chapel of the Geghard monastery.


A family praying inside the main chapel.

Yerevan

It is the capital of Armenia. The population of Yerevan is around 1.2 million people. Yerevan was named the 2012 world book capital by UNESCO.

The heart of Yerevan, is the Republic Square. It is endowed by singing fountains and it is the meeting point for all people.

The Yerevan Cascade, it is a combination of giant stairway and museum.


Contemporary art installation at Yerevan Cascade.


The singing fountains of Yerevan at Republic Square.


The Yerevan Opera Theater, opened in 1933.


The city hall of Yerevan 


The Metro station of Yerevan


The Armenian family i met at Yerevan bus Station, the young guy is now in China for his PhD studies.


The immigration control point at the Armenia border, before going to Georgia.


Tuesday, 12 February 2013

ARM interrupt context switching in Linux


Complete IRQ handling flow on ARM Linux:

Once ARM core receives interrupt, it stops execution in current context. From there on the sequence of events:

  • disables IRQ
  • copies CPSR to SPSR
  • copies current PC to LR
  • switches to IRQ mode
  • places the interrupt vector table address into PC
  • jumps to vector handler code
  • if interrupt occurred while processor was in supervisor mode, processor will switch to supervisor mode
  • irq_svc saves the registers on kernel stack, the registers(r0-r12)
  • next step is to identify irq number
  • jumps to asm_do_IRQ
  • calls handle_level_irq or handle_simple_irq or handle_edge_irq
  • calls our ISR routine
  • once ISR is completed, irq_svc will return and restore processor state by restoring registers(r0-r12), pc, cpsr

The first 6 steps is done by ARM core, not by Linux. Other steps are done by Linux. Refer to the figure below.


Kernel IRQ flow on ARM Linux:

When interrupt is detected:
  • __irq_svc - arch/arm/kernel/entry-armv.S
  • asm_do_IRQ - arch/arm/kernel/irq.c
  • handle_IRQ - arch/arm/kernel/irq.c
  • generic_handle_irq - kernel/irq/irqdesc.c
  • generic_handle_irq_desc - include/linux/irqdesc.h
  • desc->handle_irq

In arch/arm/mach-ka2000/irq.c, ka2000_irq_init(),
    irq_set_handler() is called.
In kernel/irq/chip.c, __irq_set_handler(),
    desc->handle_irq = handle
    handle can be: handle_edge_irq, handle_level_irq or handle_simple_irq. So the call to
Therefore, desc->handle_irq will jump to one of these.


For ARM Linux, the interrupt vector table is in arch/arm/kernel/entry-armv.S:

       .globl  __vectors_start
__vectors_start:
 ARM(   swi     SYS_ERROR0      )
 THUMB( svc     #0              )
 THUMB( nop                     )
        W(b)    vector_und + stubs_offset
        W(ldr)  pc, .LCvswi + stubs_offset
        W(b)    vector_pabt + stubs_offset
        W(b)    vector_dabt + stubs_offset
        W(b)    vector_addrexcptn + stubs_offset
        W(b)    vector_irq + stubs_offset
        W(b)    vector_fiq + stubs_offset

        .globl  __vectors_end
__vectors_end:

For ARM Linux, the vector handler code that runs in IRQ mode and switches to SVC mode.

        .macro  vector_stub, name, mode, correction=0
        .align  5

vector_\name:
        .if \correction
        sub     lr, lr, #\correction
        .endif

        @
        @ Save r0, lr_<exception> (parent PC) and spsr_<exception>
        @ (parent CPSR)
        @
        stmia   sp, {r0, lr}            @ save r0, lr
        mrs     lr, spsr
        str     lr, [sp, #8]              @ save spsr

        @
        @ Prepare for SVC32 mode.  IRQs remain disabled.
        @
        mrs     r0, cpsr
        eor     r0, r0, #(\mode ^ SVC_MODE | PSR_ISETSTATE)
        msr     spsr_cxsf, r0

        @
        @ the branch table must immediately follow this code
        @
        and     lr, lr, #0x0f
 THUMB( adr     r0, 1f                  )
 THUMB( ldr     lr, [r0, lr, lsl #2]    )
        mov     r0, sp
 ARM(   ldr     lr, [pc, lr, lsl #2]    )
        movs    pc, lr                  @ branch to handler in SVC mode
ENDPROC(vector_\name)

        .align  2
        @ handler addresses follow this label
1:
        .endm

Problem encountered:

A practical problem encounter in USB debugging. Linux will hang after USB controller is initialised and USB irq 32 is unmasked, when USB cable is plugged.


1.      The vector handler code will call __irq_svc, which call arch_irq_handler_default (arch/arm/include/asm/entry-macro-multi.S), which will call get_irqnr_and_base (arch/arm/mach-ka2000/include/mach/entry-macro.S).

2.      Look at get_irqnr_and_base (the code is attached below). For usb irq32, it is the first bit of the interrupt pending 2 register. The macro is entered, it branch to 6f, then branch to 4b, the condition is fulfilled, so branch to 7f. Then macro is exited with zero flag set to 1. After that, the “bne asm_do_IRQ” will not be executed, because the condition does not fulfil, and Linux is stuck in that macro.

  .macro  arch_irq_handler_default
                  get_irqnr_and_base r0, r2, r6, lr
  ……
 bne     asm_do_IRQ
 …..
.endm

3.      To fix the Linux interrupt stuck issue, add a line before the macro exit. The purpose is to set the zero flag to 0.

               .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
                ldr \irqstat, [\base, #0x18]     @ interrupt pending 1
                mov \tmp, #0
                mov \irqnr, #0
                teq \irqstat, #0
                beq 6f
4:              teq \irqstat, #1
                beq 7f
5:              mov \irqstat, \irqstat, lsr #1
                teq \irqstat, #1
                addne \irqnr, #1
                bne 5b
                add \irqnr, #1
                teq \irqstat, #0                  @irqstat=1
                bne 7f
6:              ldr \irqstat, [\base, #0x1c]      @ interrupt pending 2
                cmp \irqstat, #0
                movne \tmp, #32
                bne 4b
7:              add \irqnr, \tmp
teq \irqstat, #0
                .endm