You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
199 lines
4.7 KiB
199 lines
4.7 KiB
/*
|
|
* arch/arm64/include/asm/sec_debug.h
|
|
*
|
|
* COPYRIGHT(C) 2006-2016 Samsung Electronics Co., Ltd. All Right Reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* 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.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#ifndef SEC_DEBUG_ARM64_H
|
|
#define SEC_DEBUG_ARM64_H
|
|
|
|
#if defined(CONFIG_ARM64) && defined(CONFIG_SEC_DEBUG)
|
|
|
|
struct sec_debug_mmu_reg_t {
|
|
uint64_t TTBR0_EL1;
|
|
uint64_t TTBR1_EL1;
|
|
uint64_t TCR_EL1;
|
|
uint64_t MAIR_EL1;
|
|
uint64_t ATCR_EL1;
|
|
uint64_t AMAIR_EL1;
|
|
|
|
uint64_t HSTR_EL2;
|
|
uint64_t HACR_EL2;
|
|
uint64_t TTBR0_EL2;
|
|
uint64_t VTTBR_EL2;
|
|
uint64_t TCR_EL2;
|
|
uint64_t VTCR_EL2;
|
|
uint64_t MAIR_EL2;
|
|
uint64_t ATCR_EL2;
|
|
|
|
uint64_t TTBR0_EL3;
|
|
uint64_t MAIR_EL3;
|
|
uint64_t ATCR_EL3;
|
|
};
|
|
|
|
/* ARM CORE regs mapping structure */
|
|
struct sec_debug_core_t {
|
|
/* COMMON */
|
|
uint64_t x0;
|
|
uint64_t x1;
|
|
uint64_t x2;
|
|
uint64_t x3;
|
|
uint64_t x4;
|
|
uint64_t x5;
|
|
uint64_t x6;
|
|
uint64_t x7;
|
|
uint64_t x8;
|
|
uint64_t x9;
|
|
uint64_t x10;
|
|
uint64_t x11;
|
|
uint64_t x12;
|
|
uint64_t x13;
|
|
uint64_t x14;
|
|
uint64_t x15;
|
|
uint64_t x16;
|
|
uint64_t x17;
|
|
uint64_t x18;
|
|
uint64_t x19;
|
|
uint64_t x20;
|
|
uint64_t x21;
|
|
uint64_t x22;
|
|
uint64_t x23;
|
|
uint64_t x24;
|
|
uint64_t x25;
|
|
uint64_t x26;
|
|
uint64_t x27;
|
|
uint64_t x28;
|
|
uint64_t x29; /* sp */
|
|
uint64_t x30; /* lr */
|
|
|
|
uint64_t pc; /* pc */
|
|
uint64_t cpsr; /* cpsr */
|
|
|
|
/* EL0 */
|
|
uint64_t sp_el0;
|
|
|
|
/* EL1 */
|
|
uint64_t sp_el1;
|
|
uint64_t elr_el1;
|
|
uint64_t spsr_el1;
|
|
|
|
/* EL2 */
|
|
uint64_t sp_el2;
|
|
uint64_t elr_el2;
|
|
uint64_t spsr_el2;
|
|
|
|
/* EL3 */
|
|
/* uint64_t sp_el3; */
|
|
/* uint64_t elr_el3; */
|
|
/* uint64_t spsr_el3; */
|
|
};
|
|
|
|
#define READ_SPECIAL_REG(x) ({ \
|
|
uint64_t val; \
|
|
asm volatile ("mrs %0, " # x : "=r"(val)); \
|
|
val; \
|
|
})
|
|
|
|
static inline void sec_debug_save_mmu_reg(struct sec_debug_mmu_reg_t *mmu_reg)
|
|
{
|
|
uint64_t pstate, which_el;
|
|
|
|
pstate = READ_SPECIAL_REG(CurrentEl);
|
|
which_el = pstate & PSR_MODE_MASK;
|
|
|
|
/* pr_emerg("%s: sec_debug EL mode=%d\n", __func__,which_el); */
|
|
|
|
mmu_reg->TTBR0_EL1 = READ_SPECIAL_REG(TTBR0_EL1);
|
|
mmu_reg->TTBR1_EL1 = READ_SPECIAL_REG(TTBR1_EL1);
|
|
mmu_reg->TCR_EL1 = READ_SPECIAL_REG(TCR_EL1);
|
|
mmu_reg->MAIR_EL1 = READ_SPECIAL_REG(MAIR_EL1);
|
|
mmu_reg->AMAIR_EL1 = READ_SPECIAL_REG(AMAIR_EL1);
|
|
}
|
|
|
|
static inline void sec_debug_save_core_reg(struct sec_debug_core_t *core_reg)
|
|
{
|
|
uint64_t pstate,which_el;
|
|
|
|
pstate = READ_SPECIAL_REG(CurrentEl);
|
|
which_el = pstate & PSR_MODE_MASK;
|
|
|
|
/* pr_emerg("%s: sec_debug EL mode=%d\n", __func__,which_el); */
|
|
|
|
asm volatile (
|
|
"str x0, [%0,#0]\n\t" /* x0 is pushed first to core_reg */
|
|
"mov x0, %0\n\t"
|
|
"add x0, x0, 0x8\n\t"
|
|
"stp x1, x2, [x0], #0x10\n\t"
|
|
"stp x3, x4, [x0], #0x10\n\t"
|
|
"stp x5, x6, [x0], #0x10\n\t"
|
|
"stp x7, x8, [x0], #0x10\n\t"
|
|
"stp x9, x10, [x0], #0x10\n\t"
|
|
"stp x11, x12, [x0], #0x10\n\t"
|
|
"stp x13, x14, [x0], #0x10\n\t"
|
|
#if (!defined CONFIG_RKP_CFP_ROPP) || (defined CONFIG_RKP_CFP_TEST)
|
|
"stp x15, x16, [x0], #0x10\n\t"
|
|
"stp x17, x18, [x0], #0x10\n\t"
|
|
#else
|
|
"stp x15, xZR, [x0], #0x10\n\t"
|
|
"stp xZR, x18, [x0], #0x10\n\t"
|
|
#endif
|
|
"stp x19, x20, [x0], #0x10\n\t"
|
|
"stp x21, x22, [x0], #0x10\n\t"
|
|
"stp x23, x24, [x0], #0x10\n\t"
|
|
"stp x25, x26, [x0], #0x10\n\t"
|
|
"stp x27, x28, [x0], #0x10\n\t"
|
|
"stp x29, x30, [x0], #0x10\n\t"
|
|
|
|
/* pc */
|
|
"adr x1, .\n\t"
|
|
|
|
/* pstate */
|
|
"mrs x15, NZCV\n\t"
|
|
"bic x15, x15, #0xFFFFFFFF0FFFFFFF\n\t"
|
|
"mrs x9, DAIF\n\t"
|
|
"bic x9, x9, #0xFFFFFFFFFFFFFC3F\n\t"
|
|
"orr x15, x15, x9\n\t"
|
|
"mrs x10, CurrentEL\n\t"
|
|
"bic x10, x10, #0xFFFFFFFFFFFFFFF3\n\t"
|
|
"orr x15, x15, x10\n\t"
|
|
"mrs x11, SPSel\n\t"
|
|
"bic x11, x11, #0xFFFFFFFFFFFFFFFE\n\t"
|
|
"orr x15, x15, x11\n\t"
|
|
|
|
/* store pc & pstate */
|
|
"stp x1, x15, [x0], #0x10\n\t"
|
|
|
|
: /* output */
|
|
: "r"(core_reg) /* input */
|
|
: "%x0", "%x1" /* clobbered registers */
|
|
);
|
|
|
|
core_reg->sp_el0 = READ_SPECIAL_REG(sp_el0);
|
|
|
|
if(which_el >= PSR_MODE_EL2t){
|
|
core_reg->sp_el0 = READ_SPECIAL_REG(sp_el1);
|
|
core_reg->elr_el1 = READ_SPECIAL_REG(elr_el1);
|
|
core_reg->spsr_el1 = READ_SPECIAL_REG(spsr_el1);
|
|
core_reg->sp_el2 = READ_SPECIAL_REG(sp_el2);
|
|
core_reg->elr_el2 = READ_SPECIAL_REG(elr_el2);
|
|
core_reg->spsr_el2 = READ_SPECIAL_REG(spsr_el2);
|
|
}
|
|
}
|
|
|
|
#endif /* defined(CONFIG_ARM64) && defined(CONFIG_SEC_DEBUG) */
|
|
|
|
#endif /* SEC_DEBUG_ARM64_H */
|
|
|