Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] arm32: introduce suspend/resume common functions #1729

Merged
merged 11 commits into from
Sep 18, 2017
6 changes: 6 additions & 0 deletions core/arch/arm/include/arm32.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@
#include <stdint.h>
#include <util.h>

#define CORTEX_A7_PART_NUM 0xC07
#define CORTEX_A9_PART_NUM 0xC09

#define MIDR_PRIMARY_PART_NUM_SHIFT 4
#define MIDR_PRIMARY_PART_NUM_WIDTH 12

#define CPSR_MODE_MASK ARM32_CPSR_MODE_MASK
#define CPSR_MODE_USR ARM32_CPSR_MODE_USR
#define CPSR_MODE_FIQ ARM32_CPSR_MODE_FIQ
Expand Down
4 changes: 4 additions & 0 deletions core/arch/arm/include/arm32_macros.S
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@

/* Please keep them sorted based on the CRn register */

.macro read_midr reg
mrc p15, 0, \reg, c0, c0, 0
.endm

.macro read_ctr reg
mrc p15, 0, \reg, c0, c0, 1
.endm
Expand Down
30 changes: 30 additions & 0 deletions core/arch/arm/include/kernel/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,34 @@
#define THREAD_RPC_MAX_NUM_PARAMS 4

#ifndef ASM

#ifdef ARM64
/*
* struct thread_core_local needs to have alignment suitable for a stack
* pointer since SP_EL1 points to this
*/
#define THREAD_CORE_LOCAL_ALIGNED __aligned(16)
#else
#define THREAD_CORE_LOCAL_ALIGNED
#endif

struct thread_core_local {
vaddr_t tmp_stack_va_end;
int curr_thread;
uint32_t flags;
vaddr_t abt_stack_va_end;
#ifdef ARM32
paddr_t sm_pm_ctx_phys;
uint32_t r[2];
#endif
#ifdef ARM64
uint64_t x[4];
#endif
#ifdef CFG_TEE_CORE_DEBUG
unsigned int locked_count; /* Number of spinlocks held */
#endif
} THREAD_CORE_LOCAL_ALIGNED;

struct thread_vector_table {
uint32_t std_smc_entry;
uint32_t fast_smc_entry;
Expand Down Expand Up @@ -252,6 +280,8 @@ struct thread_handlers {
void thread_init_primary(const struct thread_handlers *handlers);
void thread_init_per_cpu(void);

struct thread_core_local *thread_get_core_local(void);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change should go into the "core: arm: kernel: make thread_core_local public" commit


/*
* Sets the stacks to be used by the different threads. Use THREAD_ID_0 for
* first stack, THREAD_ID_0 + 1 for the next and so on.
Expand Down
3 changes: 3 additions & 0 deletions core/arch/arm/include/mm/core_mmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,9 @@ static inline TEE_Result cache_op_outer(enum cache_op op __unused,
/* Check cpu mmu enabled or not */
bool cpu_mmu_enabled(void);

/* Do section mapping, not support on LPAE */
void map_memarea_sections(const struct tee_mmap_region *mm, uint32_t *ttb);

/*
* Check if platform defines nsec DDR range(s).
* Static SHM (MEM_AREA_NSEC_SHM) is not covered by this API as it is
Expand Down
50 changes: 50 additions & 0 deletions core/arch/arm/include/sm/pm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright 2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

header guards

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix in V2

#ifndef SM_PM_H
#define SM_PM_H
#include <stdint.h>
#include <types_ext.h>

struct sm_pm_ctx {
uint32_t sp;
paddr_t cpu_resume_addr;
uint32_t suspend_regs[16];
};

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a "sm_pm_" prefix to the functions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok. Will add them in next version patch

/* suspend/resume core functions */
void sm_pm_cpu_suspend_save(struct sm_pm_ctx *ptr, uint32_t sp);
void sm_pm_cpu_do_suspend(uint32_t *ptr);
void sm_pm_cpu_do_resume(void);

/*
* Exported to platform suspend, arg will be passed to fn as r0
* Return value: 0 - cpu resumed from suspended state.
* -1 - cpu not suspended.
*/
int sm_pm_cpu_suspend(uint32_t arg, int (*fn)(uint32_t));
#endif
16 changes: 14 additions & 2 deletions core/arch/arm/include/sm/psci.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <kernel/thread.h>
#include <sm/sm.h>
#include <stdint.h>

#define PSCI_FN_BASE (0x84000000U)
Expand Down Expand Up @@ -31,6 +32,17 @@
#define PSCI_AFFINITY_LEVEL_OFF 1
#define PSCI_AFFINITY_LEVEL_ON_PENDING 2

#define PSCI_POWER_STATE_ID_MASK 0xffff
#define PSCI_POWER_STATE_ID_SHIFT 0
#define PSCI_POWER_STATE_TYPE_SHIFT 16
#define PSCI_POWER_STATE_TYPE_MASK BIT32(PSCI_POWER_STATE_TYPE_SHIFT)
#define PSCI_POWER_STATE_AFFL_SHIFT 24
#define PSCI_POWER_STATE_AFFL_MASK SHIFT_U32(0x3, \
PSCI_POWER_STATE_AFFL_SHIFT)

#define PSCI_POWER_STATE_TYPE_STANDBY 0
#define PSCI_POWER_STATE_TYPE_POWER_DOWN 1

#define PSCI_RET_SUCCESS (0)
#define PSCI_RET_NOT_SUPPORTED (-1)
#define PSCI_RET_INVALID_PARAMETERS (-2)
Expand All @@ -44,7 +56,7 @@

uint32_t psci_version(void);
int psci_cpu_suspend(uint32_t power_state, uintptr_t entry,
uint32_t context_id);
uint32_t context_id, struct sm_nsec_ctx *nsec);
int psci_cpu_off(void);
int psci_cpu_on(uint32_t cpu_id, uint32_t entry, uint32_t context_id);
int psci_affinity_info(uint32_t affinity, uint32_t lowest_affnity_level);
Expand All @@ -58,6 +70,6 @@ int psci_node_hw_state(uint32_t cpu_id, uint32_t power_level);
int psci_system_suspend(uintptr_t entry, uint32_t context_id);
int psci_stat_residency(uint32_t cpu_id, uint32_t power_state);
int psci_stat_count(uint32_t cpu_id, uint32_t power_state);
void tee_psci_handler(struct thread_smc_args *args);
void tee_psci_handler(struct thread_smc_args *args, struct sm_nsec_ctx *nsec);

void psci_armv7_cpu_off(void);
2 changes: 2 additions & 0 deletions core/arch/arm/include/sm/sm.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,6 @@ static inline bool sm_platform_handler(__unused struct sm_ctx *ctx)
bool sm_platform_handler(struct sm_ctx *ctx);
#endif

void sm_save_modes_regs(struct sm_mode_regs *regs);
void sm_restore_modes_regs(struct sm_mode_regs *regs);
#endif /*SM_SM_H*/
4 changes: 3 additions & 1 deletion core/arch/arm/include/sm/std_smc.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef __STD_SMC_H__
#define __STD_SMC_H__

#include <sm/sm.h>

/* SMC function IDs for Standard Service queries */

#define ARM_STD_SVC_CALL_COUNT 0x8400ff00
Expand All @@ -18,5 +20,5 @@
#define is_psci_fid(_fid) \
(((_fid) & PSCI_FID_MASK) == PSCI_FID_VALUE)

void smc_std_handler(struct thread_smc_args *args);
void smc_std_handler(struct thread_smc_args *args, struct sm_nsec_ctx *nsec);
#endif
6 changes: 6 additions & 0 deletions core/arch/arm/kernel/asm-defines.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
*/

#include <kernel/thread.h>
#include <sm/pm.h>
#include <sm/sm.h>
#include <types_ext.h>
#include "thread_private.h"
Expand Down Expand Up @@ -55,6 +56,11 @@ DEFINES

/* struct thread_core_local */
DEFINE(THREAD_CORE_LOCAL_R0, offsetof(struct thread_core_local, r[0]));
DEFINE(THREAD_CORE_LOCAL_SM_PM_CTX_PHYS,
offsetof(struct thread_core_local, sm_pm_ctx_phys));
DEFINE(THREAD_CORE_LOCAL_SIZE, sizeof(struct thread_core_local));

DEFINE(SM_PM_CTX_SIZE, sizeof(struct sm_pm_ctx));
#endif /*ARM32*/

#ifdef ARM64
Expand Down
2 changes: 1 addition & 1 deletion core/arch/arm/kernel/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@

struct thread_ctx threads[CFG_NUM_THREADS];

static struct thread_core_local thread_core_local[CFG_TEE_CORE_NB_CORE];
struct thread_core_local thread_core_local[CFG_TEE_CORE_NB_CORE];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change should go into the "core: arm: kernel: make thread_core_local public" commit


#ifdef CFG_WITH_STACK_CANARIES
#ifdef ARM32
Expand Down
29 changes: 0 additions & 29 deletions core/arch/arm/kernel/thread_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,33 +117,6 @@ struct thread_ctx {
struct mutex_head mutexes;
struct thread_specific_data tsd;
};

#ifdef ARM64
/*
* struct thread_core_local need to have alignment suitable for a stack
* pointer since SP_EL1 points to this
*/
#define THREAD_CORE_LOCAL_ALIGNED __aligned(16)
#else
#define THREAD_CORE_LOCAL_ALIGNED
#endif

struct thread_core_local {
vaddr_t tmp_stack_va_end;
int curr_thread;
uint32_t flags;
vaddr_t abt_stack_va_end;
#ifdef ARM32
uint32_t r[2];
#endif
#ifdef ARM64
uint64_t x[4];
#endif
#ifdef CFG_TEE_CORE_DEBUG
unsigned int locked_count; /* Number of spinlocks held */
#endif
} THREAD_CORE_LOCAL_ALIGNED;

#endif /*ASM*/

#ifdef ARM64
Expand Down Expand Up @@ -190,8 +163,6 @@ void thread_init_vbar(void);
/* Handles a stdcall, r0-r7 holds the parameters */
void thread_std_smc_entry(void);

struct thread_core_local *thread_get_core_local(void);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change should go into the "core: arm: kernel: make thread_core_local public" commit

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @jenswi-linaro. I'll fix this, then add your tags.


/*
* Resumes execution of currently active thread by restoring context and
* jumping to the instruction where to continue execution.
Expand Down
3 changes: 1 addition & 2 deletions core/arch/arm/mm/core_mmu_v7.c
Original file line number Diff line number Diff line change
Expand Up @@ -742,8 +742,7 @@ static void map_page_memarea_in_pgdirs(const struct tee_mmap_region *mm,
}
}

static void map_memarea_sections(const struct tee_mmap_region *mm,
uint32_t *ttb)
void map_memarea_sections(const struct tee_mmap_region *mm, uint32_t *ttb)
{
uint32_t attr = mattr_to_desc(1, mm->attr);
size_t idx = mm->va >> SECTION_SHIFT;
Expand Down
4 changes: 4 additions & 0 deletions core/arch/arm/plat-imx/conf.mk
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,8 @@ $(call force,CFG_SECURE_TIME_SOURCE_REE,y)
CFG_BOOT_SECONDARY_REQUEST ?= y
endif

ifeq ($(filter y, $(CFG_PSCI_ARM32)), y)
CFG_HWSUPP_MEM_PERM_WXN = n
endif

ta-targets = ta_arm32
34 changes: 2 additions & 32 deletions core/arch/arm/plat-imx/imx-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,36 +89,6 @@ bool soc_is_imx6dqp(void)
return (imx_soc_type() == SOC_MX6Q) && (imx_soc_rev_major() == 2);
}

bool soc_is_imx7s(void)
{
vaddr_t addr = core_mmu_get_va(OCOTP_BASE + 0x450, MEM_AREA_IO_SEC);
uint32_t val = read32(addr);

if (soc_is_imx7ds()) {
if (val & 1)
return true;
else
return false;
}

return false;
}

bool soc_is_imx7d(void)
{
vaddr_t addr = core_mmu_get_va(OCOTP_BASE + 0x450, MEM_AREA_IO_SEC);
uint32_t val = read32(addr);

if (soc_is_imx7ds()) {
if (val & 1)
return false;
else
return true;
}

return false;
}

bool soc_is_imx7ds(void)
{
return imx_soc_type() == SOC_MX7D;
Expand All @@ -128,7 +98,7 @@ uint32_t imx_get_src_gpr(int cpu)
{
vaddr_t va = core_mmu_get_va(SRC_BASE, MEM_AREA_IO_SEC);

if (soc_is_imx7d())
if (soc_is_imx7ds())
return read32(va + SRC_GPR1_MX7 + cpu * 8 + 4);
else
return read32(va + SRC_GPR1 + cpu * 8 + 4);
Expand All @@ -138,7 +108,7 @@ void imx_set_src_gpr(int cpu, uint32_t val)
{
vaddr_t va = core_mmu_get_va(SRC_BASE, MEM_AREA_IO_SEC);

if (soc_is_imx7d())
if (soc_is_imx7ds())
write32(val, va + SRC_GPR1_MX7 + cpu * 8 + 4);
else
write32(val, va + SRC_GPR1 + cpu * 8 + 4);
Expand Down
2 changes: 0 additions & 2 deletions core/arch/arm/plat-imx/imx.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ bool soc_is_imx6sdl(void);
bool soc_is_imx6dq(void);
bool soc_is_imx6dqp(void);
bool soc_is_imx7ds(void);
bool soc_is_imx7d(void);
bool soc_is_imx7s(void);
uint32_t imx_soc_type(void);
void imx_gpcv2_set_core1_pdn_by_software(void);
void imx_gpcv2_set_core1_pup_by_software(void);
Expand Down
14 changes: 2 additions & 12 deletions core/arch/arm/plat-imx/imx7.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,6 @@
#include <tee/entry_fast.h>
#include <util.h>

register_phys_mem(MEM_AREA_IO_SEC, SRC_BASE, CORE_MMU_DEVICE_SIZE);
register_phys_mem(MEM_AREA_IO_SEC, IOMUXC_BASE, CORE_MMU_DEVICE_SIZE);
register_phys_mem(MEM_AREA_IO_SEC, CCM_BASE, CORE_MMU_DEVICE_SIZE);
register_phys_mem(MEM_AREA_IO_SEC, ANATOP_BASE, CORE_MMU_DEVICE_SIZE);
register_phys_mem(MEM_AREA_IO_SEC, GPC_BASE, CORE_MMU_DEVICE_SIZE);
register_phys_mem(MEM_AREA_IO_SEC, DDRC_BASE, CORE_MMU_DEVICE_SIZE);
register_phys_mem(MEM_AREA_IO_SEC, AIPS1_BASE, AIPS1_SIZE);
register_phys_mem(MEM_AREA_IO_SEC, AIPS2_BASE, AIPS2_SIZE);
register_phys_mem(MEM_AREA_IO_SEC, AIPS3_BASE, AIPS3_SIZE);

void plat_cpu_reset_late(void)
{
uintptr_t addr;
Expand Down Expand Up @@ -84,8 +74,8 @@ void plat_cpu_reset_late(void)
*/
write32(0x00FF0033, core_mmu_get_va(CSU_CSL_15, MEM_AREA_IO_SEC));
/*
* Proect SRC
* write32(0x003300FF, get_base(CSU_CSL_12, MEM_AREA_IO_SEC));
* Protect SRC
* write32(0x003300FF, core_mmu_get_va(CSU_CSL_12, MEM_AREA_IO_SEC));
*/
dsb();

Expand Down
Loading