Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

firmware: qcom: scm: Expose secure IO service

The secure IO service provides operations for reading and writing secure
memory from non-secure mode, expose this API through SCM.

Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: Andy Gross <andy.gross@linaro.org>

authored by

Bjorn Andersson and committed by
Andy Gross
4e659dbe e691b48d

+71
+18
drivers/firmware/qcom_scm-32.c
··· 596 596 { 597 597 return -ENODEV; 598 598 } 599 + 600 + int __qcom_scm_io_readl(struct device *dev, phys_addr_t addr, 601 + unsigned int *val) 602 + { 603 + int ret; 604 + 605 + ret = qcom_scm_call_atomic1(QCOM_SCM_SVC_IO, QCOM_SCM_IO_READ, addr); 606 + if (ret >= 0) 607 + *val = ret; 608 + 609 + return ret < 0 ? ret : 0; 610 + } 611 + 612 + int __qcom_scm_io_writel(struct device *dev, phys_addr_t addr, unsigned int val) 613 + { 614 + return qcom_scm_call_atomic2(QCOM_SCM_SVC_IO, QCOM_SCM_IO_WRITE, 615 + addr, val); 616 + }
+31
drivers/firmware/qcom_scm-64.c
··· 439 439 440 440 return ret; 441 441 } 442 + 443 + int __qcom_scm_io_readl(struct device *dev, phys_addr_t addr, 444 + unsigned int *val) 445 + { 446 + struct qcom_scm_desc desc = {0}; 447 + struct arm_smccc_res res; 448 + int ret; 449 + 450 + desc.args[0] = addr; 451 + desc.arginfo = QCOM_SCM_ARGS(1); 452 + 453 + ret = qcom_scm_call(dev, QCOM_SCM_SVC_IO, QCOM_SCM_IO_READ, 454 + &desc, &res); 455 + if (ret >= 0) 456 + *val = res.a1; 457 + 458 + return ret < 0 ? ret : 0; 459 + } 460 + 461 + int __qcom_scm_io_writel(struct device *dev, phys_addr_t addr, unsigned int val) 462 + { 463 + struct qcom_scm_desc desc = {0}; 464 + struct arm_smccc_res res; 465 + 466 + desc.args[0] = addr; 467 + desc.args[1] = val; 468 + desc.arginfo = QCOM_SCM_ARGS(2); 469 + 470 + return qcom_scm_call(dev, QCOM_SCM_SVC_IO, QCOM_SCM_IO_WRITE, 471 + &desc, &res); 472 + }
+12
drivers/firmware/qcom_scm.c
··· 333 333 } 334 334 EXPORT_SYMBOL(qcom_scm_iommu_secure_ptbl_init); 335 335 336 + int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val) 337 + { 338 + return __qcom_scm_io_readl(__scm->dev, addr, val); 339 + } 340 + EXPORT_SYMBOL(qcom_scm_io_readl); 341 + 342 + int qcom_scm_io_writel(phys_addr_t addr, unsigned int val) 343 + { 344 + return __qcom_scm_io_writel(__scm->dev, addr, val); 345 + } 346 + EXPORT_SYMBOL(qcom_scm_io_writel); 347 + 336 348 /** 337 349 * qcom_scm_is_available() - Checks if SCM is available 338 350 */
+6
drivers/firmware/qcom_scm.h
··· 30 30 #define QCOM_SCM_CMD_CORE_HOTPLUGGED 0x10 31 31 extern void __qcom_scm_cpu_power_down(u32 flags); 32 32 33 + #define QCOM_SCM_SVC_IO 0x5 34 + #define QCOM_SCM_IO_READ 0x1 35 + #define QCOM_SCM_IO_WRITE 0x2 36 + extern int __qcom_scm_io_readl(struct device *dev, phys_addr_t addr, unsigned int *val); 37 + extern int __qcom_scm_io_writel(struct device *dev, phys_addr_t addr, unsigned int val); 38 + 33 39 #define QCOM_SCM_SVC_INFO 0x6 34 40 #define QCOM_IS_CALL_AVAIL_CMD 0x1 35 41 extern int __qcom_scm_is_call_available(struct device *dev, u32 svc_id,
+4
include/linux/qcom_scm.h
··· 43 43 extern int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare); 44 44 extern int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size); 45 45 extern int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare); 46 + extern int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val); 47 + extern int qcom_scm_io_writel(phys_addr_t addr, unsigned int val); 46 48 #else 47 49 static inline 48 50 int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus) ··· 75 73 static inline int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare) { return -ENODEV; } 76 74 static inline int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size) { return -ENODEV; } 77 75 static inline int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare) { return -ENODEV; } 76 + static inline int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val) { return -ENODEV; } 77 + static inline int qcom_scm_io_writel(phys_addr_t addr, unsigned int val) { return -ENODEV; } 78 78 #endif 79 79 #endif