178 lines
3.2 KiB
ArmAsm
178 lines
3.2 KiB
ArmAsm
.global cortexa8_ena_int
|
|
cortexa8_ena_int:
|
|
cpsie i
|
|
bx lr
|
|
|
|
.global cortexa8_dis_int
|
|
cortexa8_dis_int:
|
|
cpsid i
|
|
bx lr
|
|
|
|
.global cortexa8_get_int
|
|
cortexa8_get_int:
|
|
mrs r0, cpsr
|
|
ands r0, r0, #0x80
|
|
moveq r0, #1
|
|
movne r0, #0
|
|
bx lr
|
|
|
|
.global cortexa8_set_abt_sp
|
|
cortexa8_set_abt_sp:
|
|
/* Read and save CPSR */
|
|
mrs r1, cpsr
|
|
/* Set mode to ABT */
|
|
cps #0x17
|
|
/* Set SP in ABT mode */
|
|
mov sp, r0
|
|
/* Restore original CPSR */
|
|
msr cpsr, r1
|
|
/* Return */
|
|
bx lr
|
|
|
|
.global cortexa8_set_und_sp
|
|
cortexa8_set_und_sp:
|
|
/* Read and save CPSR */
|
|
mrs r1, cpsr
|
|
/* Set mode to UND */
|
|
cps #0x1b
|
|
/* Set SP in UND mode */
|
|
mov sp, r0
|
|
/* Restore original CPSR */
|
|
msr cpsr, r1
|
|
/* Return */
|
|
bx lr
|
|
|
|
.global cortexa8_set_irq_sp
|
|
cortexa8_set_irq_sp:
|
|
/* Read and save CPSR */
|
|
mrs r1, cpsr
|
|
/* Set mode to IRQ */
|
|
cps #0x12
|
|
/* Set SP in IRQ mode */
|
|
mov sp, r0
|
|
/* Restore original CPSR */
|
|
msr cpsr, r1
|
|
/* Return */
|
|
bx lr
|
|
|
|
.global cortexa8_set_fiq_sp
|
|
cortexa8_set_fiq_sp:
|
|
/* Read and save CPSR */
|
|
mrs r1, cpsr
|
|
/* Set mode to FIQ */
|
|
cps #0x11
|
|
/* Set SP in FIQ mode */
|
|
mov sp, r0
|
|
/* Restore original CPSR */
|
|
msr cpsr, r1
|
|
/* Return */
|
|
bx lr
|
|
|
|
.global cortexa8_get_spsr
|
|
cortexa8_get_spsr:
|
|
mrs r0, spsr
|
|
bx lr
|
|
|
|
.global cortexa8_get_cpsr
|
|
cortexa8_get_cpsr:
|
|
mrs r0, cpsr
|
|
bx lr
|
|
|
|
/*
|
|
The irq sp (r13) register is loaded with a pointer to the current thread control block.
|
|
All registers are saved there, the sp is loaded with __stack_int and the
|
|
interrupt handler is called.
|
|
The (possibly changed) current thread control block is used to restore context and return.
|
|
*/
|
|
.global _cortexa8_int
|
|
_cortexa8_int:
|
|
/* If we are not interrupting user or system mode, jump to _cortexa8_inner_int (no context switch) */
|
|
mrs r13, spsr
|
|
and r13, r13, #0x1f
|
|
teq r13, #0x1f
|
|
teqne r13, #0x10
|
|
bne _cortexa8_inner_int
|
|
|
|
ldr r13, = _current_thread_cb
|
|
ldr r13, [r13]
|
|
stm r13, {r0-r14}^
|
|
add lr, lr, #-4
|
|
str lr, [r13, #60]
|
|
mrs r0, spsr
|
|
str r0, [r13, #64]
|
|
ldr r13, = __stack_int
|
|
|
|
bl _omap35x_intc_handler
|
|
|
|
ldr r13, = _current_thread_cb
|
|
ldr r13, [r13]
|
|
ldr r1, [r13, #64]
|
|
msr spsr, r1
|
|
ldr lr, [r13, #60]
|
|
ldm r13, {r0-r14}^
|
|
movs pc,lr
|
|
|
|
_cortexa8_inner_int:
|
|
ldr r13, = __stack_int
|
|
push {lr}
|
|
add r13, r13, #-60
|
|
stm r13, {r0-r14}
|
|
mrs r0, spsr
|
|
push {r0}
|
|
|
|
bl _omap35x_intc_handler
|
|
|
|
pop {r0}
|
|
msr spsr, r0
|
|
ldm r13, {r0-r15}^
|
|
|
|
|
|
.global _cortexa8_syscall
|
|
_cortexa8_syscall:
|
|
ldr r13, = _current_thread_cb
|
|
ldr r13, [r13]
|
|
stm r13, {r0-r14}^
|
|
str lr, [r13, #60]
|
|
mrs r0, spsr
|
|
str r0, [r13, #64]
|
|
ldr r13, = __stack_syscall
|
|
|
|
/* Determine if the calling thread was executing ARM or Thumb code */
|
|
tst r0, #0x20
|
|
/* For Thumb, read syscall no. from LR-2, for ARM from LR-4 */
|
|
ldreq r0, [lr, #-4]
|
|
biceq r0, #0xff000000
|
|
ldrneh r0, [lr, #-2]
|
|
andne r0, #0x000000ff
|
|
|
|
bl syscall_handler
|
|
|
|
ldr r13, = _current_thread_cb
|
|
ldr r13, [r13]
|
|
ldr r1, [r13, #64]
|
|
msr spsr, r1
|
|
ldr lr, [r13, #60]
|
|
ldm r13, {r0-r14}^
|
|
movs pc,lr
|
|
|
|
.global _vect_table
|
|
.align 5
|
|
_vect_table:
|
|
/* Reset / unused */
|
|
nop
|
|
/* Undefined instruction */
|
|
b _cortexa8_excp_undef
|
|
/* Supervisor call */
|
|
b _cortexa8_syscall
|
|
/* Prefetch abort */
|
|
b _cortexa8_excp_pf_abt
|
|
/* Data abort */
|
|
b _cortexa8_excp_data_abt
|
|
/* Unused */
|
|
nop
|
|
/* IRQ */
|
|
b _cortexa8_int
|
|
/* FIQ */
|
|
b _cortexa8_unhandled_fiq
|
|
|