[arm64] only save partial registers on irq entry
Patch by Vidya Sagar: saves and restores only regs 0~17 as 18~30 are already being saved in context switch API for irq and fiq exceptions
This commit is contained in:
@@ -35,6 +35,7 @@ ldp \ra, \rb, [sp], #16
|
||||
|
||||
#define lr x30
|
||||
#define regsave_long_offset 0xf0
|
||||
#define regsave_short_offset 0x90
|
||||
|
||||
.macro regsave_long
|
||||
sub sp, sp, #32
|
||||
@@ -60,6 +61,24 @@ stp lr, x0, [sp, #regsave_long_offset]
|
||||
stp x1, x2, [sp, #regsave_long_offset + 16]
|
||||
.endm
|
||||
|
||||
.macro regsave_short
|
||||
sub sp, sp, #32
|
||||
push x16, x17
|
||||
push x14, x15
|
||||
push x12, x13
|
||||
push x10, x11
|
||||
push x8, x9
|
||||
push x6, x7
|
||||
push x4, x5
|
||||
push x2, x3
|
||||
push x0, x1
|
||||
add x0, sp, #regsave_short_offset
|
||||
mrs x1, elr_el1
|
||||
mrs x2, spsr_el1
|
||||
stp lr, x0, [sp, #regsave_short_offset]
|
||||
stp x1, x2, [sp, #regsave_short_offset + 16]
|
||||
.endm
|
||||
|
||||
.macro regrestore_long
|
||||
ldr lr, [sp, #regsave_long_offset]
|
||||
ldp x1, x2, [sp, #regsave_long_offset + 16]
|
||||
@@ -83,6 +102,23 @@ pop x28, x29
|
||||
add sp, sp, #32
|
||||
.endm
|
||||
|
||||
.macro regrestore_short
|
||||
ldr lr, [sp, #regsave_short_offset]
|
||||
ldp x1, x2, [sp, #regsave_short_offset + 16]
|
||||
msr elr_el1, x1
|
||||
msr spsr_el1, x2
|
||||
pop x0, x1
|
||||
pop x2, x3
|
||||
pop x4, x5
|
||||
pop x6, x7
|
||||
pop x8, x9
|
||||
pop x10, x11
|
||||
pop x12, x13
|
||||
pop x14, x15
|
||||
pop x16, x17
|
||||
add sp, sp, #32
|
||||
.endm
|
||||
|
||||
.macro invalid_exception, which
|
||||
regsave_long
|
||||
mov x1, #\which
|
||||
@@ -115,21 +151,21 @@ LOCAL_FUNCTION(arm64_sync_exc_current_el_SPx)
|
||||
regsave_long
|
||||
mov x0, sp
|
||||
bl arm64_sync_exception
|
||||
b arm64_exc_shared_restore
|
||||
b arm64_exc_shared_restore_long
|
||||
|
||||
.org 0x280
|
||||
LOCAL_FUNCTION(arm64_irq_current_el_SPx)
|
||||
regsave_long
|
||||
regsave_short
|
||||
mov x0, sp
|
||||
bl platform_irq
|
||||
b arm64_exc_shared_restore
|
||||
b arm64_exc_shared_restore_short
|
||||
|
||||
.org 0x300
|
||||
LOCAL_FUNCTION(arm64_fiq_current_el_SPx)
|
||||
regsave_long
|
||||
regsave_short
|
||||
mov x0, sp
|
||||
bl platform_fiq
|
||||
b arm64_exc_shared_restore
|
||||
b arm64_exc_shared_restore_short
|
||||
|
||||
.org 0x380
|
||||
LOCAL_FUNCTION(arm64_err_exc_current_el_SPx)
|
||||
@@ -169,7 +205,10 @@ LOCAL_FUNCTION(arm64_fiq_lower_el_32)
|
||||
LOCAL_FUNCTION(arm64_err_exc_lower_el_32)
|
||||
invalid_exception 0x33
|
||||
|
||||
LOCAL_FUNCTION(arm64_exc_shared_restore)
|
||||
LOCAL_FUNCTION(arm64_exc_shared_restore_long)
|
||||
regrestore_long
|
||||
eret
|
||||
|
||||
LOCAL_FUNCTION(arm64_exc_shared_restore_short)
|
||||
regrestore_short
|
||||
eret
|
||||
|
||||
@@ -53,6 +53,12 @@ struct arm64_iframe_long {
|
||||
uint64_t spsr;
|
||||
};
|
||||
|
||||
struct arm64_iframe_short {
|
||||
uint64_t r[20];
|
||||
uint64_t elr;
|
||||
uint64_t spsr;
|
||||
};
|
||||
|
||||
extern void arm64_exception_base(void);
|
||||
void arm64_el3_to_el1(void);
|
||||
|
||||
|
||||
@@ -179,7 +179,7 @@ status_t unmask_interrupt(unsigned int vector)
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
enum handler_return platform_irq(struct arm64_iframe_long *frame)
|
||||
enum handler_return platform_irq(struct arm64_iframe_short *frame)
|
||||
{
|
||||
uint32_t iar = GICCPUREG(IAR);
|
||||
uint vector = iar & 0x3ff;
|
||||
@@ -217,7 +217,7 @@ enum handler_return platform_irq(struct arm64_iframe_long *frame)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void platform_fiq(struct arm64_iframe_long *frame)
|
||||
void platform_fiq(struct arm64_iframe_short *frame)
|
||||
{
|
||||
PANIC_UNIMPLEMENTED;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user