kernel_samsung_a53x/include/soc/samsung/exynos-s2mpu.h
2024-06-15 16:02:09 -03:00

265 lines
7.2 KiB
C
Executable file

/*
* Copyright (c) 2019 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
* EXYNOS - Stage 2 Protection Unit(S2MPU)
* Author: Junho Choi <junhosj.choi@samsung.com>
*
* 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.
*/
#ifndef __EXYNOS_S2MPU_H__
#define __EXYNOS_S2MPU_H__
#define EXYNOS_MAX_S2MPU_INSTANCE (64)
#define EXYNOS_MAX_SUBSYSTEM (32)
#define EXYNOS_MAX_SUBSYSTEM_NAME_LEN (16)
#define SUBSYSTEM_FW_NUM_SHIFT (32)
#define SUBSYSTEM_INDEX_SHIFT (0)
/* Error */
#define ERROR_INVALID_SUBSYSTEM_NAME (0x1)
#define ERROR_DO_NOT_SUPPORT_SUBSYSTEM (0x2)
#define ERROR_INVALID_FW_BIN_INFO (0x3)
#define ERROR_INVALID_NOTIFIER_BLOCK (0x4)
#define ERROR_INVALID_PARAMETER (0x5)
#define ERROR_S2MPU_NOT_INITIALIZED (0xE12E0001)
/* Backup and restore S2MPU */
#define EXYNOS_PD_S2MPU_BACKUP (0)
#define EXYNOS_PD_S2MPU_RESTORE (1)
/* S2MPU fault */
#define MAX_VID_OF_S2MPU_FAULT_INFO (8)
#define FAULT_TYPE_MPTW_ACCESS_FAULT (0x1)
#define FAULT_TYPE_AP_FAULT (0x2)
#define FAULT_TYPE_CONTEXT_FAULT (0x4)
#define FAULT_THIS_ADDR_IS_NOT_BLACKLIST (0xFFFF)
#define S2MPU_CONTEXT_VALID_SHIFT (3)
#define S2MPU_CONTEXT_VID_SHIFT (0)
#define S2MPU_CONTEXT_VALID_MASK (0x1)
#define S2MPU_CONTEXT_VID_MASK (0x7)
#define OWNER_IS_KERNEL_RO (99)
#define OWNER_IS_TEST (98)
#define ERROR_NOTHING_S2MPU_FAULT (0x2)
/* Return values from SMC */
#define S2MPUFD_ERROR_INVALID_CH_NUM (0x600)
#define S2MPUFD_ERROR_INVALID_FAULT_INFO_SIZE (0x601)
/* S2MPU Notifier */
#define S2MPU_NOTIFIER_SET (1)
#define S2MPU_NOTIFIER_UNSET (0)
#define S2MPU_NOTIFIER_PANIC (0xFF00000000)
#define S2MPU_NOTIFY_OK (0)
#define S2MPU_NOTIFY_BAD (1)
/* S2MPU enable check */
#define S2_BUF_SIZE (30)
/* MPTC */
#define NUM_OF_MPTC_WAY (4)
#define S2MPU_MAX_NUM_OF_FAULT_MPTC (2)
#define S2MPU_FAULT_STLB_INDEX (0)
#define S2MPU_FAULT_PTLB_INDEX (1)
/* For backward compatibility */
#define exynos_verify_subsystem_fw exynos_s2mpu_verify_subsystem_fw
#define exynos_request_fw_stage2_ap exynos_s2mpu_request_fw_stage2_ap
/* PM QoS for SSS */
#define PM_QOS_SSS_UPDATE (true)
#define PM_QOS_SSS_RELEASE (false)
#define PM_QOS_SSS_FREQ_DOMAIN_LEN (8)
#ifndef __ASSEMBLY__
#include <linux/mutex.h>
#include <soc/samsung/exynos_pm_qos.h>
/* S2MPU access permission */
enum stage2_ap {
ATTR_NO_ACCESS = 0x0,
ATTR_RO = 0x1,
ATTR_WO = 0x2,
ATTR_RW = 0x3
};
/* Registers of S2MPUFD Fault Information */
struct s2mpu_mptc {
uint32_t valid;
uint32_t ppn;
uint32_t vid;
uint32_t granule;
uint32_t ap;
};
struct s2mpu_fault_mptc {
uint32_t set;
struct s2mpu_mptc mptc[NUM_OF_MPTC_WAY];
};
struct __s2mpu_fault_info {
unsigned int fault_addr_low;
unsigned int fault_addr_high;
unsigned int vid;
unsigned int type;
unsigned int rw;
unsigned int len;
unsigned int axid;
unsigned int context;
unsigned int subsystem;
unsigned int blacklist_owner;
struct s2mpu_fault_mptc fault_mptc[S2MPU_MAX_NUM_OF_FAULT_MPTC];
};
struct s2mpu_fault_info {
unsigned int fault_cnt;
struct __s2mpu_fault_info info[MAX_VID_OF_S2MPU_FAULT_INFO];
};
/* Structure of notifier info */
struct s2mpu_notifier_info {
const char *subsystem;
unsigned long fault_addr;
unsigned int fault_rw;
unsigned int fault_len;
unsigned int fault_type;
};
/* Structure of notifier block */
struct s2mpu_notifier_block {
const char *subsystem;
int (*notifier_call)(struct s2mpu_notifier_block *,
struct s2mpu_notifier_info *);
};
/* Data structure for S2MPU Fault Information */
struct s2mpu_info_data {
struct device *dev;
struct s2mpu_fault_info *fault_info;
dma_addr_t fault_info_pa;
unsigned int instance_num;
unsigned int irq[EXYNOS_MAX_S2MPU_INSTANCE];
unsigned int irqcnt;
struct s2mpu_notifier_info *noti_info;
unsigned int *notifier_flag;
};
/* PM QoS for SSS */
struct s2mpu_pm_qos_sss {
struct exynos_pm_qos_request qos_sss;
unsigned int sss_freq_domain;
unsigned int qos_sss_freq;
unsigned int qos_count;
struct mutex qos_count_lock;
bool need_qos_sss;
};
unsigned long exynos_s2mpu_set_stage2_ap(const char *subsystem,
unsigned long base,
unsigned long size,
unsigned int ap);
unsigned long exynos_s2mpu_set_blacklist(const char *subsystem,
unsigned long base,
unsigned long size);
unsigned long exynos_s2mpu_set_all_blacklist(unsigned long base,
unsigned long size);
/**
* exynos_s2mpu_verify_subsystem_fw - Verify the signature of sub-system FW.
*
* @subsystem: Sub-system name.
* Please refer to subsystem-names property of s2mpu node
* in exynosXXXX-security.dtsi.
* @fw_id: FW ID of this subsystem.
* @fw_base: FW base address.
* It's physical address(PA) and should be aligned with 64KB
* because of S2MPU granule.
* @fw_bin_size: FW binary size.
* It should be aligned with 4bytes because of the limit of
* signature verification.
* @fw_mem_size: The size to be used by FW.
* This memory region needs to be protected from other
* sub-systems. It should be aligned with 64KB like fw_base
* because of S2MPU granlue.
*/
unsigned long exynos_s2mpu_verify_subsystem_fw(const char *subsystem,
unsigned int fw_id,
unsigned long fw_base,
size_t fw_bin_size,
size_t fw_mem_size);
/**
* exynos_s2mpu_request_fw_stage2_ap - Request Stage 2 access permission
* of FW to allow access memory.
*
* @subsystem: Sub-system name.
* Please refer to subsystem-names property of s2mpu node
* in exynosXXXX-security.dtsi.
*
* This function must be called in case that only sub-system FW is
* verified.
*/
unsigned long exynos_s2mpu_request_fw_stage2_ap(const char *subsystem);
/**
* exynos_s2mpu_release_fw_stage2_ap - Release Stage 2 access permission
* for sub-system FW region and block
* all Stage 2 access permission of
* the sub-system.
*
* @subsystem: Sub-system name
* Please refer to subsystem-names property of
* s2mpu node in exynosXXXX-security.dtsi.
* @fw_id: FW ID of this subsystem
*
* This function must be called in case that only sub-system FW is verified.
*/
unsigned long exynos_s2mpu_release_fw_stage2_ap(const char *subsystem,
uint32_t fw_id);
/**
* exynos_s2mpu_notifier_call_register - Register subsystem's S2MPU notifier call.
*
* @s2mpu_notifier_block: S2MPU Notifier structure
* It should have two elements.
* One is Sub-system's name, 'subsystem'.
* The other is notifier call function pointer,
* s2mpu_notifier_fn_t 'notifier_call'.
* @'subsystem': Please refer to subsystem-names property of s2mpu
* node in exynosXXXX-security.dtsi.
* @'notifier_call' It's type is s2mpu_notifier_fn_t.
* And it should return S2MPU_NOTIFY
*/
unsigned long exynos_s2mpu_notifier_call_register(struct s2mpu_notifier_block *snb);
#ifdef CONFIG_EXYNOS_S2MPU_PD
unsigned long exynos_pd_backup_s2mpu(unsigned int pd);
unsigned long exynos_pd_restore_s2mpu(unsigned int pd);
#else
static inline unsigned long exynos_pd_backup_s2mpu(unsigned int pd)
{
return 0;
}
static inline unsigned long exynos_pd_restore_s2mpu(unsigned int pd)
{
return 0;
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __EXYNOS_S2MPU_H__ */