Skip to content

Commit 101dc3f

Browse files
JosephChen2017rkhuangtao
authored andcommitted
firmware: rockchip_sip: compatible 64-bit ATF works with 32-bit kernel
maily compatible for fiq debugger. Change-Id: I26cb735fa38997d64c7d080b96d04a29d0146b71 Signed-off-by: chenjh <chenjh@rock-chips.com>
1 parent e8686e1 commit 101dc3f

2 files changed

Lines changed: 147 additions & 39 deletions

File tree

drivers/firmware/rockchip_sip.c

Lines changed: 98 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,17 @@ struct arm_smccc_res sip_smc_soc_bus_div(u32 arg0, u32 arg1, u32 arg2)
153153
}
154154

155155
/************************** fiq debugger **************************************/
156+
/*
157+
* AArch32 is not allowed to call SMC64(ATF framework does not support), so we
158+
* don't change SIP_UARTDBG_FN to SIP_UARTDBG_CFG64 even when cpu is AArch32
159+
* mode. Let ATF support SIP_UARTDBG_CFG, and we just initialize SIP_UARTDBG_FN
160+
* depends on compile option(CONFIG_ARM or CONFIG_ARM64).
161+
*/
156162
#ifdef CONFIG_ARM64
157163
#define SIP_UARTDBG_FN SIP_UARTDBG_CFG64
158164
#else
159165
#define SIP_UARTDBG_FN SIP_UARTDBG_CFG
166+
static int firmware_64_32bit;
160167
#endif
161168

162169
static int fiq_sip_enabled;
@@ -174,47 +181,76 @@ static struct pt_regs sip_fiq_debugger_get_pt_regs(void *reg_base,
174181
unsigned long sp_el1)
175182
{
176183
struct pt_regs fiq_pt_regs;
184+
__maybe_unused struct sm_nsec_ctx *nsec_ctx = reg_base;
185+
__maybe_unused struct gp_regs_ctx *gp_regs = reg_base;
177186

178187
#ifdef CONFIG_ARM64
179-
/* copy cpu context */
188+
/*
189+
* 64-bit ATF + 64-bit kernel
190+
*/
191+
/* copy cpu context: x0 ~ spsr_el3 */
180192
memcpy(&fiq_pt_regs, reg_base, 8 * 31);
181193

182-
/* copy pstate */
194+
/* copy pstate: spsr_el3 */
183195
memcpy(&fiq_pt_regs.pstate, reg_base + 0x110, 8);
184196
fiq_pt_regs.sp = sp_el1;
185197

186-
/* copy pc */
198+
/* copy pc: elr_el3 */
187199
memcpy(&fiq_pt_regs.pc, reg_base + 0x118, 8);
188200
#else
189-
struct sm_nsec_ctx *nsec_ctx = reg_base;
190-
191-
fiq_pt_regs.ARM_r0 = nsec_ctx->r0;
192-
fiq_pt_regs.ARM_r1 = nsec_ctx->r1;
193-
fiq_pt_regs.ARM_r2 = nsec_ctx->r2;
194-
fiq_pt_regs.ARM_r3 = nsec_ctx->r3;
195-
fiq_pt_regs.ARM_r4 = nsec_ctx->r4;
196-
fiq_pt_regs.ARM_r5 = nsec_ctx->r5;
197-
fiq_pt_regs.ARM_r6 = nsec_ctx->r6;
198-
fiq_pt_regs.ARM_r7 = nsec_ctx->r7;
199-
fiq_pt_regs.ARM_r8 = nsec_ctx->r8;
200-
fiq_pt_regs.ARM_r9 = nsec_ctx->r9;
201-
fiq_pt_regs.ARM_r10 = nsec_ctx->r10;
202-
fiq_pt_regs.ARM_fp = nsec_ctx->r11;
203-
fiq_pt_regs.ARM_ip = nsec_ctx->r12;
204-
fiq_pt_regs.ARM_sp = nsec_ctx->svc_sp;
205-
fiq_pt_regs.ARM_lr = nsec_ctx->svc_lr;
206-
fiq_pt_regs.ARM_cpsr = nsec_ctx->mon_spsr;
207-
208-
/*
209-
* 'nsec_ctx->mon_lr' is not the fiq break point's PC, because it will
210-
* be override as 'psci_fiq_debugger_uart_irq_tf_cb' for optee-os to
211-
* jump to fiq_debugger handler.
212-
*
213-
* As 'nsec_ctx->und_lr' is not used for kernel, so optee-os uses it to
214-
* deliver fiq break point's PC.
215-
*
216-
*/
217-
fiq_pt_regs.ARM_pc = nsec_ctx->und_lr;
201+
if (firmware_64_32bit == FIRMWARE_ATF_64BIT) {
202+
/*
203+
* 64-bit ATF + 32-bit kernel
204+
*/
205+
fiq_pt_regs.ARM_r0 = gp_regs->x0;
206+
fiq_pt_regs.ARM_r1 = gp_regs->x1;
207+
fiq_pt_regs.ARM_r2 = gp_regs->x2;
208+
fiq_pt_regs.ARM_r3 = gp_regs->x3;
209+
fiq_pt_regs.ARM_r4 = gp_regs->x4;
210+
fiq_pt_regs.ARM_r5 = gp_regs->x5;
211+
fiq_pt_regs.ARM_r6 = gp_regs->x6;
212+
fiq_pt_regs.ARM_r7 = gp_regs->x7;
213+
fiq_pt_regs.ARM_r8 = gp_regs->x8;
214+
fiq_pt_regs.ARM_r9 = gp_regs->x9;
215+
fiq_pt_regs.ARM_r10 = gp_regs->x10;
216+
fiq_pt_regs.ARM_fp = gp_regs->x11;
217+
fiq_pt_regs.ARM_ip = gp_regs->x12;
218+
fiq_pt_regs.ARM_sp = gp_regs->x19; /* aarch32 svc_r13 */
219+
fiq_pt_regs.ARM_lr = gp_regs->x18; /* aarch32 svc_r14 */
220+
fiq_pt_regs.ARM_cpsr = gp_regs->spsr_el3;
221+
fiq_pt_regs.ARM_pc = gp_regs->elr_el3;
222+
} else {
223+
/*
224+
* 32-bit tee firmware + 32-bit kernel
225+
*/
226+
fiq_pt_regs.ARM_r0 = nsec_ctx->r0;
227+
fiq_pt_regs.ARM_r1 = nsec_ctx->r1;
228+
fiq_pt_regs.ARM_r2 = nsec_ctx->r2;
229+
fiq_pt_regs.ARM_r3 = nsec_ctx->r3;
230+
fiq_pt_regs.ARM_r4 = nsec_ctx->r4;
231+
fiq_pt_regs.ARM_r5 = nsec_ctx->r5;
232+
fiq_pt_regs.ARM_r6 = nsec_ctx->r6;
233+
fiq_pt_regs.ARM_r7 = nsec_ctx->r7;
234+
fiq_pt_regs.ARM_r8 = nsec_ctx->r8;
235+
fiq_pt_regs.ARM_r9 = nsec_ctx->r9;
236+
fiq_pt_regs.ARM_r10 = nsec_ctx->r10;
237+
fiq_pt_regs.ARM_fp = nsec_ctx->r11;
238+
fiq_pt_regs.ARM_ip = nsec_ctx->r12;
239+
fiq_pt_regs.ARM_sp = nsec_ctx->svc_sp;
240+
fiq_pt_regs.ARM_lr = nsec_ctx->svc_lr;
241+
fiq_pt_regs.ARM_cpsr = nsec_ctx->mon_spsr;
242+
243+
/*
244+
* 'nsec_ctx->mon_lr' is not the fiq break point's PC, because it will
245+
* be override as 'psci_fiq_debugger_uart_irq_tf_cb' for optee-os to
246+
* jump to fiq_debugger handler.
247+
*
248+
* As 'nsec_ctx->und_lr' is not used for kernel, so optee-os uses it to
249+
* deliver fiq break point's PC.
250+
*
251+
*/
252+
fiq_pt_regs.ARM_pc = nsec_ctx->und_lr;
253+
}
218254
#endif
219255

220256
return fiq_pt_regs;
@@ -328,23 +364,47 @@ void sip_fiq_debugger_enable_fiq(bool enable, uint32_t tgt_cpu)
328364

329365
/******************************************************************************/
330366
#ifdef CONFIG_ARM
331-
/*
332-
* optee work on kernel 3.10 and 4.4, and we have different sip
333-
* implement. We should tell optee the current rockchip sip version.
334-
*/
335-
static __init int sip_implement_version_init(void)
367+
static __init int sip_firmware_init(void)
336368
{
337369
struct arm_smccc_res res;
338370

339371
if (!psci_smp_available())
340372
return 0;
341373

374+
/*
375+
* OP-TEE works on kernel 3.10 and 4.4 and we have different sip
376+
* implement. We should tell OP-TEE the current rockchip sip version.
377+
*/
342378
res = __invoke_sip_fn_smc(SIP_SIP_VERSION, SIP_IMPLEMENT_V2,
343379
SECURE_REG_WR, 0);
344380
if (IS_SIP_ERROR(res.a0))
345381
pr_err("%s: set rockchip sip version v2 failed\n", __func__);
346382

383+
/*
384+
* Currently, we support:
385+
*
386+
* 1. 64-bit ATF + 64-bit kernel;
387+
* 2. 64-bit ATF + 32-bit kernel;
388+
* 3. 32-bit TEE + 32-bit kernel;
389+
*
390+
* We need to detect which case of above and record in firmware_64_32bit
391+
* We get info from cpuid and compare with all supported ARMv7 cpu.
392+
*/
393+
switch (read_cpuid_part()) {
394+
case ARM_CPU_PART_CORTEX_A7:
395+
case ARM_CPU_PART_CORTEX_A8:
396+
case ARM_CPU_PART_CORTEX_A9:
397+
case ARM_CPU_PART_CORTEX_A12:
398+
case ARM_CPU_PART_CORTEX_A15:
399+
case ARM_CPU_PART_CORTEX_A17:
400+
firmware_64_32bit = FIRMWARE_TEE_32BIT;
401+
break;
402+
default:
403+
firmware_64_32bit = FIRMWARE_ATF_64BIT;
404+
break;
405+
}
406+
347407
return 0;
348408
}
349-
arch_initcall(sip_implement_version_init);
409+
arch_initcall(sip_firmware_init);
350410
#endif

include/linux/rockchip/rockchip_sip.h

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,14 @@
8989
/* wakeup state */
9090
#define REMOTECTL_PWRKEY_WAKEUP 0xdeadbeaf
9191

92+
enum {
93+
FIRMWARE_NONE,
94+
FIRMWARE_TEE_32BIT,
95+
FIRMWARE_ATF_32BIT,
96+
FIRMWARE_ATF_64BIT,
97+
FIRMWARE_END,
98+
};
99+
92100
/* Share mem page types */
93101
typedef enum {
94102
SHARE_PAGE_TYPE_INVALID = 0,
@@ -212,7 +220,7 @@ static inline int sip_fiq_debugger_switch_cpu(u32 cpu) { return 0; }
212220
static inline int sip_fiq_debugger_is_enabled(void) { return 0; }
213221
#endif
214222

215-
/* optee cpu_context */
223+
/* 32-bit OP-TEE context, never change order of members! */
216224
struct sm_nsec_ctx {
217225
u32 usr_sp;
218226
u32 usr_lr;
@@ -248,4 +256,44 @@ struct sm_nsec_ctx {
248256
u32 r3;
249257
};
250258

259+
/* 64-bit ATF context, never change order of members! */
260+
struct gp_regs_ctx {
261+
u64 x0;
262+
u64 x1;
263+
u64 x2;
264+
u64 x3;
265+
u64 x4;
266+
u64 x5;
267+
u64 x6;
268+
u64 x7;
269+
u64 x8;
270+
u64 x9;
271+
u64 x10;
272+
u64 x11;
273+
u64 x12;
274+
u64 x13;
275+
u64 x14;
276+
u64 x15;
277+
u64 x16;
278+
u64 x17;
279+
u64 x18;
280+
u64 x19;
281+
u64 x20;
282+
u64 x21;
283+
u64 x22;
284+
u64 x23;
285+
u64 x24;
286+
u64 x25;
287+
u64 x26;
288+
u64 x27;
289+
u64 x28;
290+
u64 x29;
291+
u64 lr;
292+
u64 sp_el0;
293+
u64 scr_el3;
294+
u64 runtime_sp;
295+
u64 spsr_el3;
296+
u64 elr_el3;
297+
};
298+
251299
#endif

0 commit comments

Comments
 (0)