blob: 15cd3b7a2d2db89c0fe0be8a001fa9fe82f6e966 [file] [log] [blame] [edit]
/**
* Copyright (c) 2011 Trusted Logic S.A.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
.text
#define SMICODEPUB_IRQ_END 0xFE
#define SMICODEPUB_FIQ_END 0xFD
#define SMICODEPUB_RPC_END 0xFC
#define PUB2SEC_NOCST 0xFF
#define SMICODEPUB_NEWTASK 0x00
/*
* RPC status:
* - 0: the secure world yielded due to an interrupt
* - 1: the secure world yielded on an RPC (no public thread is handling it)
* - 2: the secure world yielded on an RPC and the response is ready
*/
#define RPC_ADVANCEMENT_NONE 0
#define RPC_ADVANCEMENT_PENDING 1
#define RPC_ADVANCEMENT_FINISHED 2
#ifdef CONFIG_ARM_ERRATA_430973
#define INVALIDATE_BTB MCR p15, 0, R0, c7, c5, 6
#else
#define INVALIDATE_BTB
#endif
schedule_secure_world:
.global schedule_secure_world
/* Save registers */
push {r4-r12, lr}
/* Copy the Secure Service ID in r12 */
mov r12, r0
cmp r0, #SMICODEPUB_IRQ_END
beq return_from_irq
cmp r0, #SMICODEPUB_RPC_END
beq return_from_rpc
mov r6, #PUB2SEC_NOCST
mov r12, #SMICODEPUB_NEWTASK
b label_smc
return_from_rpc:
ldr r9, =g_RPC_parameters
ldm r9, {r0-r3}
/* fall through */
return_from_irq:
ldr r10, =g_secure_task_id
ldr r6, [r10]
b label_smc
label_smc:
INVALIDATE_BTB
dsb
dmb
#ifdef CONFIG_BENCH_SECURE_CYCLE
/* Come from Non Secure: activate counter 1 (write to 0 are ignored) */
mov r4, #0x00000002
/* Read Count Enable Set Register */
mcr p15, 0x0, r4, c9, c12, 1
/* Come from Non Secure: stop counter 0 (write to 0 are ignored) */
mov r4, #0x00000001
/* Write Count Enable Clear Register */
mcr p15, 0x0, r4, c9, c12, 2
#endif
smc #0
b service_end
nop
#ifdef CONFIG_BENCH_SECURE_CYCLE
/* Come from Secure: activate counter 0 (write to 0 are ignored) */
mov r4, #0x00000001
/* Write Count Enable Set Register */
mcr p15, 0x0, r4, c9, c12, 1
/* Come from Secure: stop counter 1 (write to 0 are ignored) */
mov r4, #0x00000002
/* Write Count Enable Clear Register */
mcr p15, 0x0, r4, c9, c12, 2
#endif
INVALIDATE_BTB
ldr r8, =g_secure_task_id
str r6, [r8]
mov r0, #0x00
ldr r8, =g_service_end
str r0, [r8]
b schedule_secure_world_exit
service_end:
schedule_secure_world_exit:
#ifdef CONFIG_BENCH_SECURE_CYCLE
/* Come from Secure: activate counter 0 (write to 0 are ignored) */
mov r4, #0x00000001
/* Write Count Enable Set Register */
mcr p15, 0x0, r4, c9, c12, 1
/* Come from Secure: stop counter 1 (write to 0 are ignored) */
mov r4, #0x00000002
/* Write Count Enable Clear Register */
mcr p15, 0x0, r4, c9, c12, 2
#endif
INVALIDATE_BTB
/* Restore registers */
pop {r4-r12, pc}
rpc_handler:
.global rpc_handler
#ifdef CONFIG_BENCH_SECURE_CYCLE
/* Come from Secure: activate counter 0 (write to 0 are ignored) */
mov r4, #0x00000001
/* Write Count Enable Set Register */
mcr p15, 0x0, r4, c9, c12, 1
/* Come from Secure: stop counter 1 (write to 0 are ignored) */
mov r4, #0x00000002
/* Write Count Enable Clear Register */
mcr p15, 0x0, r4, c9, c12, 2
#endif
INVALIDATE_BTB
/* g_RPC_advancement = RPC_ADVANCEMENT_PENDING */
ldr r8, =g_RPC_advancement
mov r9, #RPC_ADVANCEMENT_PENDING
str r9, [r8]
ldr r8, =g_RPC_parameters
stm r8, {r0-r3}
ldr r8, =g_secure_task_id
str r6, [r8]
mov r0, #0x00
ldr r8, =g_service_end
str r0, [r8]
/* Restore registers */
pop {r4-r12, pc}
#ifdef CONFIG_BENCH_SECURE_CYCLE
setup_counters:
.global setup_counters
push {r14}
mrc p15, 0, r2, c9, c12, 0
orr r2, r2, #0x3
mcr p15, 0, r2, c9, c12, 0
mrc p15, 0, r2, c9, c12, 1
orr r2, r2, #0x80000000
mcr p15, 0, r2, c9, c12, 1
pop {pc}
run_code_speed:
.global run_code_speed
push {r14}
/* Reset cycle counter */
mov r2, #0
mcr p15, 0, r2, c9, c13, 0
run_code_speed_loop:
sub r0, r0, #1
cmp r0, #0
bne run_code_speed_loop
/* Read cycle counter */
mrc p15, 0, r0, c9, c13, 0
pop {pc}
run_data_speed:
.global run_data_speed
push {r14}
/* Reset cycle counter */
mov r2, #0
mcr p15, 0, r2, c9, c13, 0
run_data_speed_loop:
sub r0, r0, #1
ldr r2, [r1]
cmp r0, #0
bne run_data_speed_loop
/* read cycle counter */
mrc p15, 0, r0, c9, c13, 0
pop {pc}
#endif
read_mpidr:
.global read_mpidr
mrc p15, 0, r0, c0, c0, 5
bx lr