SmartAudio/lichee/linux-4.9/drivers/soc/sunxi/pm/mem_cpu_asm.S

381 lines
20 KiB
ArmAsm
Executable File

/*
* mem support specific for ARM
* based on hibernate support specific for ARM
* Copyright (C) 2010 Nokia Corporation
* Copyright (C) 2010 Texas Instruments, Inc.
* Copyright (C) 2006 Rafael J. Wysocki <rjw <at> sisk.pl>
*
* Contact: Hiroshi DOYU <Hiroshi.DOYU <at> nokia.com>
*
* License terms: GNU General Public License (GPL) version 2
*/
#include <linux/linkage.h>
/*
* function: mem_arch_suspend
* discription: save main part of general purpose register.
*/
.text
.globl mem_arch_suspend
mem_arch_suspend:
push {r0-r3}
/*
* Save current program status register
*/
ldr r3, .Lsaved_cpsr_svc
mrs r0, cpsr
str r0, [r3]
/*
* Change to system(user) mode
*/
mov r1, r0
orr r1, r1, #0x1f
msr cpsr_c, r1
/*
* Save User context
*/
ldr r3, .Lsaved_context_r13_sys
stmia r3, {r13-r14}
/*
* Change to fiq mode
*/
mov r1, r0
bic r1, r1, #0x1f
orr r1, r1, #0x11
msr cpsr_c, r1
/*
* Save fiq context
*/
ldr r3, .Lsaved_context_r13_fiq
stmia r3, {r8-r14}
ldr r3, .Lsaved_spsr_fiq
mrs r1, spsr
str r1, [r3]
/*
* Change to abt mode
*/
mov r1, r0
bic r1, r1, #0x1f
orr r1, r1, #0x17
msr cpsr_c, r1
/*
* Save abt context
*/
ldr r3, .Lsaved_context_r13_abt
stmia r3, {r13-r14}
ldr r3, .Lsaved_spsr_abt
mrs r1, spsr
str r1, [r3]
/*
* Change to irq mode
*/
mov r1, r0
bic r1, r1, #0x1f
orr r1, r1, #0x12
msr cpsr_c, r1
/*
* Save irq context
*/
ldr r3, .Lsaved_context_r13_irq
stmia r3, {r13-r14}
ldr r3, .Lsaved_spsr_irq
mrs r1, spsr
str r1, [r3]
/*
* Change to und mode
*/
mov r1, r0
bic r1, r1, #0x1f
orr r1, r1, #0x1b
msr cpsr_c, r1
/*
* Save und context
*/
ldr r3, .Lsaved_context_r13_und
stmia r3, {r13-r14}
ldr r3, .Lsaved_spsr_und
mrs r1, spsr
str r1, [r3]
/*
* Change to mon mode
*/
mov r1, r0
bic r1, r1, #0x1f
orr r1, r1, #0x16
msr cpsr_c, r1
/*
* Save mon context
*/
ldr r3, .Lsaved_context_r13_mon
stmia r3, {r13-r14}
ldr r3, .Lsaved_spsr_mon
mrs r1, spsr
str r1, [r3]
/*
* Go back to original SVC mode
*/
msr cpsr_c, r0
/*
* Save SVC context
*/
ldr r3, .Lsaved_context_r12_svc
stmia r3, {r12-r13}
ldr r3, .Lsaved_spsr_svc
mrs r1, spsr
str r1, [r3]
pop {r0-r3}
/*
* return
*/
mov pc, lr
/*
* function: mem_arch_resume
* discription: retore main part of general purpose register.
*/
.align 4
.globl mem_arch_resume
mem_arch_resume:
push {r0-r3}
mrs r0, cpsr
/*
* Restore SVC context
*/
ldr r3, .Lsaved_context_r12_svc
ldmia r3, {r12-r13}
ldr r3, .Lsaved_spsr_svc
ldr r1, [r3]
msr spsr_cxsf, r1
/*
* Change to system(user) mode
*/
mov r1, r0
orr r1, r1, #0x1f
msr cpsr_c, r1
/*
* Restore User context
*/
ldr r3, .Lsaved_context_r13_sys
ldmia r3, {r13-r14}
/*
* Change to fiq mode
*/
mov r1, r0
bic r1, r1, #0x1f
orr r1, r1, #0x11
msr cpsr_c, r1
/*
* Restore fiq context
*/
ldr r3, .Lsaved_context_r13_fiq
ldmia r3, {r8-r14}
ldr r3, .Lsaved_spsr_fiq
ldr r1, [r3]
msr spsr_cxsf, r1
/*
* Change to abt mode
*/
mov r1, r0
bic r1, r1, #0x1f
orr r1, r1, #0x17
msr cpsr_c, r1
/*
* Restore abt context
*/
ldr r3, .Lsaved_context_r13_abt
ldmia r3, {r13-r14}
ldr r3, .Lsaved_spsr_abt
ldr r1, [r3]
msr spsr_cxsf, r1
/*
* Change to irq mode
*/
mov r1, r0
bic r1, r1, #0x1f
orr r1, r1, #0x12
msr cpsr_c, r1
/*
* Restore irq context
*/
ldr r3, .Lsaved_context_r13_irq
ldmia r3, {r13-r14}
ldr r3, .Lsaved_spsr_irq
ldr r1, [r3]
msr spsr_cxsf, r1
/*
* Change to und mode
*/
mov r1, r0
bic r1, r1, #0x1f
orr r1, r1, #0x1b
msr cpsr_c, r1
/*
* Restore und context
*/
ldr r3, .Lsaved_context_r13_und
ldmia r3, {r13-r14}
ldr r3, .Lsaved_spsr_und
ldr r1, [r3]
msr spsr_cxsf, r1
/*
* Change to mon mode
*/
mov r1, r0
bic r1, r1, #0x1f
orr r1, r1, #0x16
msr cpsr_c, r1
/*
* Restore mon context
*/
ldr r3, .Lsaved_context_r13_mon
ldmia r3, {r13-r14}
ldr r3, .Lsaved_spsr_mon
ldr r1, [r3]
msr spsr_cxsf, r1
/*
* Restore CPSR, and Change to svc mode
*/
ldr r3, .Lsaved_cpsr_svc
ldr r1, [r3]
msr cpsr_cxsf, r1
/*
* Flush TLB (Invalidate unified TLB unlocked entries)
*/
mov r1, #0
mcr p15, 0, r1, c8, c7, 0
pop {r0-r3}
/* Set the return value */
mov r0, #0
/* return*/
mov pc, lr
.align 4
ENTRY(mem_clear_runtime_context)
push {r0-r3}
/*
* Save empty context for clear r0 - r10
*/
ldr r3, .Lsaved_empty_context_svc
mov r0, #0
str r0, [r3], #0x4
str r0, [r3], #0x4
str r0, [r3], #0x4
str r0, [r3], #0x4
str r0, [r3], #0x4
str r0, [r3], #0x4
str r0, [r3], #0x4
str r0, [r3], #0x4
str r0, [r3], #0x4
str r0, [r3], #0x4
str r0, [r3], #0x4
/*
* clear SVC context
*/
ldr r3, .Lsaved_empty_context_svc
ldmia r3, {r0-r10}
pop {r0-r3}
/* return*/
mov pc, lr
ENDPROC(mem_clear_runtime_context)
.align 4
ENTRY(disable_prefetch)
push {r0-r3}
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #(0x1 << 11) //Disable all forms of branch prediction
mcr p15, 0, r0, c1, c0, 0
// enable invalidate btb ...
mrc p15, 0, r0, c1, c0, 1
orr r0, r0, #(0x11 << 0) //Invalidate BTB, disable indirect predictor
orr r0, r0, #(0x1 << 15) //Forces in-order issue in branch execution unit
orr r0, r0, #(0xE << 20) //Disable L2 TLB prefetching, force in-order load issue, force in-order requests to the same set and way
mcr p15, 0, r0, c1, c0, 1
pop {r0-r3}
/* return*/
mov pc, lr
ENDPROC(disable_prefetch)
.align 4
.globl save_runtime_context
save_runtime_context:
/*save r0-r13 register*/
stmia r0, {r0 - r13}
mov pc, lr
.align 4
.globl clear_reg_context
clear_reg_context:
/*clear r0-r11 register*/
mov r0, #0
mov r1, #0
mov r2, #0
mov r3, #0
mov r4, #0
mov r5, #0
mov r6, #0
mov r7, #0
mov r8, #0
mov r9, #0
mov r10,#0
mov r11,#0
mov r12,#0
mov pc, lr
.Lsaved_context_r13_sys: .long saved_context_r13_sys
.Lsaved_cpsr_svc: .long saved_cpsr_svc
.Lsaved_context_r12_svc: .long saved_context_r12_svc
.Lsaved_spsr_svc: .long saved_spsr_svc
.Lsaved_context_r13_fiq: .long saved_context_r13_fiq
.Lsaved_spsr_fiq: .long saved_spsr_fiq
.Lsaved_context_r13_abt: .long saved_context_r13_abt
.Lsaved_spsr_abt: .long saved_spsr_abt
.Lsaved_context_r13_irq: .long saved_context_r13_irq
.Lsaved_spsr_irq: .long saved_spsr_irq
.Lsaved_context_r13_und: .long saved_context_r13_und
.Lsaved_spsr_und: .long saved_spsr_und
.Lsaved_context_r13_mon: .long saved_context_r13_mon
.Lsaved_spsr_mon: .long saved_spsr_mon
.Lsaved_empty_context_svc: .long saved_empty_context_svc