Commit cf906b2a authored by Leon Chen's avatar Leon Chen
Browse files

Refactor MediaTek platform common code

Refactor MediaTek platform common code for further mt6795 upstream.
parent 72c1dc14
Showing with 496 additions and 36 deletions
+496 -36
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* 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.
*/
#include <arch.h>
#include <arch_helpers.h>
#include <assert.h>
#include <debug.h>
#include <oem_svc.h>
#include <platform.h>
#include <runtime_svc.h>
#include <stdint.h>
#include <uuid.h>
/* OEM Service UUID */
DEFINE_SVC_UUID(oem_svc_uid,
0xb943add0, 0x069d, 0x11e4, 0x91, 0x91,
0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66);
/* Setup OEM Services */
static int32_t oem_svc_setup(void)
{
/*
* Invoke related module setup from here
*/
return 0;
}
/*******************************************************************************
* OEM top level handler for servicing SMCs.
******************************************************************************/
uint64_t oem_smc_handler(uint32_t smc_fid,
uint64_t x1,
uint64_t x2,
uint64_t x3,
uint64_t x4,
void *cookie,
void *handle,
uint64_t flags)
{
uint64_t rc;
switch (smc_fid) {
default:
rc = SMC_UNK;
WARN("Unimplemented OEM Call: 0x%x\n", smc_fid);
}
SMC_RET1(handle, rc);
}
/*
* Top-level OEM Service SMC handler. This handler will in turn dispatch
* calls to related SMC handler
*/
uint64_t oem_svc_smc_handler(uint32_t smc_fid,
uint64_t x1,
uint64_t x2,
uint64_t x3,
uint64_t x4,
void *cookie,
void *handle,
uint64_t flags)
{
/*
* Dispatch OEM calls to OEM Common handler and return its return value
*/
if (is_oem_fid(smc_fid)) {
return oem_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
handle, flags);
}
switch (smc_fid) {
case OEM_SVC_CALL_COUNT:
/*
* Return the number of OEM Service Calls.
*/
SMC_RET1(handle, OEM_SVC_NUM_CALLS);
case OEM_SVC_UID:
/* Return UID to the caller */
SMC_UUID_RET(handle, oem_svc_uid);
case OEM_SVC_VERSION:
/* Return the version of current implementation */
SMC_RET2(handle, OEM_VERSION_MAJOR, OEM_VERSION_MINOR);
default:
WARN("Unimplemented OEM Service Call: 0x%x\n", smc_fid);
SMC_RET1(handle, SMC_UNK);
}
}
/* Register OEM Service Calls as runtime service */
DECLARE_RT_SVC(
oem_svc,
OEN_OEM_START,
OEN_OEM_END,
SMC_TYPE_FAST,
oem_svc_setup,
oem_svc_smc_handler
);
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* 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.
*/
#ifndef __OEM_SVC_H__
#define __OEM_SVC_H__
/*******************************************************************************
* Defines for runtime services func ids
******************************************************************************/
/*
* Number of OEM calls (above) implemented.
*/
#define OEM_SVC_NUM_CALLS 3
/*******************************************************************************
* Defines for OEM Service queries
******************************************************************************/
/* 0x83000000 - 0x8300FEFF is OEM service calls */
#define OEM_SVC_CALL_COUNT 0x8300ff00
#define OEM_SVC_UID 0x8300ff01
/* 0x8300ff02 is reserved */
#define OEM_SVC_VERSION 0x8300ff03
/* 0x8300ff04 - 0x8300FFFF is reserved for future expansion */
/* OEM Service Calls version numbers */
#define OEM_VERSION_MAJOR 0x0
#define OEM_VERSION_MINOR 0x1
/* The macros below are used to identify OEM calls from the SMC function ID */
/* SMC32 ID range from 0x83000000 to 0x83000FFF */
/* SMC64 ID range from 0xC3000000 to 0xC3000FFF */
#define OEM_FID_MASK 0xf000u
#define OEM_FID_VALUE 0u
#define is_oem_fid(_fid) \
(((_fid) & OEM_FID_MASK) == OEM_FID_VALUE)
#define OEM_SVC_E_SUCCESS 0
#define OEM_SVC_E_NOT_SUPPORTED -1
#define OEM_SVC_E_INVALID_PARAMS -2
#endif /* __OEM_SVC_H__ */
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* 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.
*/
#include <arch_helpers.h>
#include <arm_gic.h>
#include <bl_common.h>
#include <cci.h>
#include <console.h>
#include <debug.h>
#include <mmio.h>
#include <mtk_plat_common.h>
#include <mtk_sip_svc.h>
#include <platform.h>
#include <plat_private.h>
#include <xlat_tables.h>
struct atf_arg_t gteearg;
void clean_top_32b_of_param(uint32_t smc_fid,
uint64_t *px1,
uint64_t *px2,
uint64_t *px3,
uint64_t *px4)
{
/* if parameters from SMC32. Clean top 32 bits */
if (0 == (smc_fid & SMC_AARCH64_BIT)) {
*px1 = *px1 & SMC32_PARAM_MASK;
*px2 = *px2 & SMC32_PARAM_MASK;
*px3 = *px3 & SMC32_PARAM_MASK;
*px4 = *px4 & SMC32_PARAM_MASK;
}
}
#if MTK_SIP_KERNEL_BOOT_ENABLE
static struct kernel_info k_info;
static void save_kernel_info(uint64_t pc,
uint64_t r0,
uint64_t r1,
uint64_t k32_64)
{
k_info.k32_64 = k32_64;
k_info.pc = pc;
if (LINUX_KERNEL_32 == k32_64) {
/* for 32 bits kernel */
k_info.r0 = 0;
/* machtype */
k_info.r1 = r0;
/* tags */
k_info.r2 = r1;
} else {
/* for 64 bits kernel */
k_info.r0 = r0;
k_info.r1 = r1;
}
}
uint64_t get_kernel_info_pc(void)
{
return k_info.pc;
}
uint64_t get_kernel_info_r0(void)
{
return k_info.r0;
}
uint64_t get_kernel_info_r1(void)
{
return k_info.r1;
}
uint64_t get_kernel_info_r2(void)
{
return k_info.r2;
}
void boot_to_kernel(uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4)
{
static uint8_t kernel_boot_once_flag;
/* only support in booting flow */
if (0 == kernel_boot_once_flag) {
kernel_boot_once_flag = 1;
console_init(gteearg.atf_log_port,
UART_CLOCK, UART_BAUDRATE);
INFO("save kernel info\n");
save_kernel_info(x1, x2, x3, x4);
bl31_prepare_kernel_entry(x4);
INFO("el3_exit\n");
console_uninit();
}
}
#endif
uint32_t plat_get_spsr_for_bl33_entry(void)
{
unsigned int mode;
uint32_t spsr;
unsigned int ee;
unsigned long daif;
INFO("Secondary bootloader is AArch32\n");
mode = MODE32_svc;
ee = 0;
/*
* TODO: Choose async. exception bits if HYP mode is not
* implemented according to the values of SCR.{AW, FW} bits
*/
daif = DAIF_ABT_BIT | DAIF_IRQ_BIT | DAIF_FIQ_BIT;
spsr = SPSR_MODE32(mode, 0, ee, daif);
return spsr;
}
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* 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.
*/
#ifndef __MTK_PLAT_COMMON_H__
#define __MTK_PLAT_COMMON_H__
#include <stdint.h>
/*******************************************************************************
* Function and variable prototypes
******************************************************************************/
#define DEVINFO_SIZE 4
#define LINUX_KERNEL_32 0
#define SMC32_PARAM_MASK (0xFFFFFFFF)
struct atf_arg_t {
unsigned int atf_magic;
unsigned int tee_support;
unsigned int tee_entry;
unsigned int tee_boot_arg_addr;
unsigned int hwuid[4]; /* HW Unique id for t-base used */
unsigned int HRID[2]; /* HW random id for t-base used */
unsigned int atf_log_port;
unsigned int atf_log_baudrate;
unsigned int atf_log_buf_start;
unsigned int atf_log_buf_size;
unsigned int atf_irq_num;
unsigned int devinfo[DEVINFO_SIZE];
unsigned int atf_aee_debug_buf_start;
unsigned int atf_aee_debug_buf_size;
};
struct kernel_info {
uint64_t pc;
uint64_t r0;
uint64_t r1;
uint64_t r2;
uint64_t k32_64;
};
struct mtk_bl_param_t {
uint64_t bootarg_loc;
uint64_t bootarg_size;
uint64_t bl33_start_addr;
uint64_t tee_info_addr;
};
/* Declarations for mtk_plat_common.c */
uint32_t plat_get_spsr_for_bl32_entry(void);
uint32_t plat_get_spsr_for_bl33_entry(void);
void clean_top_32b_of_param(uint32_t smc_fid, uint64_t *x1,
uint64_t *x2,
uint64_t *x3,
uint64_t *x4);
void bl31_prepare_kernel_entry(uint64_t k32_64);
void enable_ns_access_to_cpuectlr(void);
void boot_to_kernel(uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4);
uint64_t get_kernel_info_pc(void);
uint64_t get_kernel_info_r0(void);
uint64_t get_kernel_info_r1(void);
uint64_t get_kernel_info_r2(void);
extern struct atf_arg_t gteearg;
#endif
......@@ -28,7 +28,10 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <assert.h>
#include <console.h>
#include <debug.h>
#include <mmio.h>
#include <mtk_plat_common.h>
#include <mtk_sip_svc.h>
#include <runtime_svc.h>
#include <uuid.h>
......@@ -38,41 +41,65 @@ DEFINE_SVC_UUID(mtk_sip_svc_uid,
0xf7582ba4, 0x4262, 0x4d7d, 0x80, 0xe5,
0x8f, 0x95, 0x05, 0x00, 0x0f, 0x3d);
#pragma weak mediatek_plat_sip_handler
uint64_t mediatek_plat_sip_handler(uint32_t smc_fid,
uint64_t x1,
uint64_t x2,
uint64_t x3,
uint64_t x4,
void *cookie,
void *handle,
uint64_t flags)
{
ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
SMC_RET1(handle, SMC_UNK);
}
/*
* This function handles Mediatek defined SiP Calls */
static uint64_t mediatek_sip_handler(uint32_t smc_fid,
uint64_t x1,
uint64_t x2,
uint64_t x3,
uint64_t x4,
void *cookie,
void *handle)
uint64_t mediatek_sip_handler(uint32_t smc_fid,
uint64_t x1,
uint64_t x2,
uint64_t x3,
uint64_t x4,
void *cookie,
void *handle,
uint64_t flags)
{
uint64_t ret;
switch (smc_fid) {
case MTK_SIP_SET_AUTHORIZED_SECURE_REG:
ret = mt_sip_set_authorized_sreg((uint32_t)x1, (uint32_t)x2);
SMC_RET1(handle, ret);
case MTK_SIP_PWR_ON_MTCMOS:
ret = mt_sip_pwr_on_mtcmos((uint32_t)x1);
SMC_RET1(handle, ret);
uint32_t ns;
case MTK_SIP_PWR_OFF_MTCMOS:
ret = mt_sip_pwr_off_mtcmos((uint32_t)x1);
SMC_RET1(handle, ret);
/* if parameter is sent from SMC32. Clean top 32 bits */
clean_top_32b_of_param(smc_fid, &x1, &x2, &x3, &x4);
case MTK_SIP_PWR_MTCMOS_SUPPORT:
ret = mt_sip_pwr_mtcmos_support();
SMC_RET1(handle, ret);
/* Determine which security state this SMC originated from */
ns = is_caller_non_secure(flags);
if (!ns) {
/* SiP SMC service secure world's call */
;
} else {
/* SiP SMC service normal world's call */
switch (smc_fid) {
#if MTK_SIP_SET_AUTHORIZED_SECURE_REG_ENABLE
case MTK_SIP_SET_AUTHORIZED_SECURE_REG: {
/* only use ret here */
uint64_t ret;
default:
ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
break;
ret = mt_sip_set_authorized_sreg((uint32_t)x1,
(uint32_t)x2);
SMC_RET1(handle, ret);
}
#endif
#if MTK_SIP_KERNEL_BOOT_ENABLE
case MTK_SIP_KERNEL_BOOT_AARCH32:
boot_to_kernel(x1, x2, x3, x4);
SMC_RET0(handle);
#endif
}
}
SMC_RET1(handle, SMC_UNK);
return mediatek_plat_sip_handler(smc_fid, x1, x2, x3, x4,
cookie, handle, flags);
}
/*
......@@ -87,13 +114,6 @@ uint64_t sip_smc_handler(uint32_t smc_fid,
void *handle,
uint64_t flags)
{
uint32_t ns;
/* Determine which security state this SMC originated from */
ns = is_caller_non_secure(flags);
if (!ns)
SMC_RET1(handle, SMC_UNK);
switch (smc_fid) {
case SIP_SVC_CALL_COUNT:
/* Return the number of Mediatek SiP Service Calls. */
......@@ -110,7 +130,7 @@ uint64_t sip_smc_handler(uint32_t smc_fid,
default:
return mediatek_sip_handler(smc_fid, x1, x2, x3, x4,
cookie, handle);
cookie, handle, flags);
}
}
......
......@@ -42,6 +42,8 @@
#define MTK_SIP_SVC_VERSION_MAJOR 0x0
#define MTK_SIP_SVC_VERSION_MINOR 0x1
#define SMC_AARCH64_BIT 0x40000000
/* Number of Mediatek SiP Calls implemented */
#define MTK_SIP_NUM_CALLS 4
......@@ -51,10 +53,19 @@
#define MTK_SIP_PWR_OFF_MTCMOS 0x82000403
#define MTK_SIP_PWR_MTCMOS_SUPPORT 0x82000404
/* For MTK SMC from Secure OS */
/* 0x82000000 - 0x820000FF & 0xC2000000 - 0xC20000FF */
#define MTK_SIP_KERNEL_BOOT_AARCH32 0x82000200
#define MTK_SIP_KERNEL_BOOT_AARCH64 0xC2000200
/* Mediatek SiP Calls error code */
enum {
MTK_SIP_E_SUCCESS = 0,
MTK_SIP_E_INVALID_PARAM = -1
MTK_SIP_E_INVALID_PARAM = -1,
MTK_SIP_E_NOT_SUPPORTED = -2,
MTK_SIP_E_INVALID_RANGE = -3,
MTK_SIP_E_PERMISSION_DENY = -4,
MTK_SIP_E_LOCK_FAIL = -5
};
/*
......
......@@ -55,6 +55,7 @@ BL31_SOURCES += drivers/arm/cci/cci.c \
lib/cpus/aarch64/cortex_a57.S \
lib/cpus/aarch64/cortex_a72.S \
plat/common/aarch64/platform_mp_stack.S \
${MTK_PLAT}/common/mtk_plat_common.c \
${MTK_PLAT}/common/mtk_sip_svc.c \
${MTK_PLAT_SOC}/aarch64/plat_helpers.S \
${MTK_PLAT_SOC}/aarch64/platform_common.c \
......@@ -87,3 +88,5 @@ ERRATA_A53_836870 := 1
# indicate the reset vector address can be programmed
PROGRAMMABLE_RESET_ADDRESS := 1
$(eval $(call add_define,MTK_SIP_SET_AUTHORIZED_SECURE_REG_ENABLE))
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment