HIKEY OP-TEE切换UART运行状态

2024-05-05 04:18

本文主要是介绍HIKEY OP-TEE切换UART运行状态,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

已经实现了UART的安全状态的切换。打算基于此继续开发OPTEE_OS相应的各类驱动。
一.资源准备

OPTEE工程源码:OPTEE官网
注意:根据说明下载hikey_debian的代码版本。

二.实现方法

1.Hikey_Debian的代码版本带有helloworld的样例TA,可以修改为调用静态TA,当然也可以自行编写TA调用静态TA,调用方法前文讲述过了,不再累述。

2.下载OPTEE工程源码后,本身不能支持静态TA的编译和调用,需修改配置文件,修改方法参见:静态TA配置

3.修改/devel/optee/optee_os/core/arch/arm/plat-hikey/platform_config.h文件,经过与OP-TEE官方咨询,确定Hikey TZPC的基地址为0xF8002000,大小为0x878,修改内容如下:

...
...
#define CONSOLE_UART_BASE       0xF7113000
#else
#error Unknown console UART
#endif+/* TZPC */
+#define TZPC_BASE          0xF8002000
+#define TZPC_SIZE          0x878#define CONSOLE_BAUDRATE    115200
#define CONSOLE_UART_CLK_IN_HZ  19200000...
...

4.修改/devel/optee/optee_os/core/arch/arm/plat-hikey/main.c文件,默认的OP-TEE的可访问硬件地址中不包含TZPC的地址,需要自行添加进去,TZPC的地址位于安全世界下,则地址空间属性为MEM_AREA_IO_SEC,由于需要切换UART的运行状态,同样需要修改UART的地址权限也为SEC,也就是访问EL1下的地址,修改内容如下:


...
....cpu_suspend = pm_do_nothing,.cpu_resume = pm_do_nothing,.system_off = pm_do_nothing,.system_reset = pm_do_nothing,
};-register_phys_mem(MEM_AREA_IO_SEC, CONSOLE_UART_BASE, PL011_REG_SIZE);
+register_phys_mem(MEM_AREA_IO_SEC, CONSOLE_UART_BASE, PL011_REG_SIZE);+register_phys_mem(MEM_AREA_IO_SEC, TZPC_BASE, TZPC_SIZE);const struct thread_handlers *generic_boot_get_handlers(void)
{return &handlers;
}
...
...

4.在/devel/optee/optee_os/core/arch/arm/sta/目录下,新建sta_reg.c文件,作为静态TA文件,内容如下:

#include <compiler.h>
#include <stdio.h>
#include <trace.h>
#include <kernel/static_ta.h>
#include <string.h>
#include <string_ext.h>
#include <mm/tee_pager.h>
#include <mm/core_memprot.h>#include <drivers/pl011.h>#include <io.h> #define TA_NAME     "sta_reg.ta"#define STA_REG_UUID \{ 0xd96a5b40, 0x12c7, 0x21af, \{ 0x87, 0x94, 0x10, 0x02, 0xa5, 0xd5, 0xc6, 0x1b } }#define STA_READ_STATS      0
#define STA_WRITE_STATS     1#define CONSOLE_UART_BASE       0xF7113000/* flag register */
/* TZPC */ 
#define TZPC_BASE          0xF8002000
#define TZPC_SIZE          0x878#define SLAVE_PROTX_STATE    0x830#define SLAVE_PROTX_SET    0x834#define SLAVE_PROTX_CLEAN    0x838/*
#define set_sec_uart0     (1 << 26) UART0 设置安全状态
#define set_sec_uart1     (1 << 27) UART1 设置安全状态
#define set_sec_uart2     (1 << 28) UART2 设置安全状态
#define set_sec_uart3     (1 << 29) UART3 设置安全状态
#define set_sec_uart4     (1 << 30) UART4 设置安全状态*/static vaddr_t console_base(void)
{static void *va;if (cpu_mmu_enabled()) {if (!va)va = phys_to_virt(CONSOLE_UART_BASE, MEM_AREA_IO_SEC);return (vaddr_t)va;}return CONSOLE_UART_BASE;
}static vaddr_t tzpc_base(void)
{static void *va;if (cpu_mmu_enabled()) {if (!va)va = phys_to_virt(TZPC_BASE, MEM_AREA_IO_SEC);return (vaddr_t)va;}return TZPC_BASE;
}static TEE_Result read_regs(uint32_t type __unused, TEE_Param p[4] __unused)
{  EMSG("TZPC_UART_STATE: 0x%x\n",read32(tzpc_base()+SLAVE_PROTX_STATE));   return TEE_SUCCESS;
}static TEE_Result write_regs(uint32_t type __unused, TEE_Param p[4] __unused)
{ vaddr_t uart_base = console_base();int ch;MSG("TZPC_WRITE_UART:on the write");write32(0xFF000000, tzpc_base()+SLAVE_PROTX_SET);DMSG("TZPC_WRITE_UART:on the write finish");DMSG("welcome into the secure world!\n");DMSG("please input 'a' to back the normal world!\n");DMSG("TZPC_UART_STATE: 0x%x\n",read32(tzpc_base()+SLAVE_PROTX_STATE)); do{ch = pl011_getchar(uart_base);}while(ch != 97)write32(0xFFFFFFFF, tzpc_base()+SLAVE_PROTX_CLEAN);DMSG("have been back to the normal world!\n");return TEE_SUCCESS;
}/** Trusted Application Entry Points*/static TEE_Result create_ta(void)
{return TEE_SUCCESS;
}static void destroy_ta(void)
{
}static TEE_Result open_session(uint32_t ptype __unused,TEE_Param params[4] __unused,void **ppsess __unused)
{return TEE_SUCCESS;
}static void close_session(void *psess __unused)
{
}static TEE_Result invoke_command(void *psess __unused,uint32_t cmd, uint32_t ptypes,TEE_Param params[4])
{switch (cmd) {case STA_READ_STATS:return read_regs(ptypes, params);case STA_WRITE_STATS:return write_regs(ptypes, params);default:break;}return TEE_ERROR_BAD_PARAMETERS;
}static_ta_register(.uuid = STA_REG_UUID, .name = TA_NAME,.create_entry_point = create_ta,.destroy_entry_point = destroy_ta,.open_session_entry_point = open_session,.close_session_entry_point = close_session,.invoke_command_entry_point = invoke_command);

这个静态TA的主要功能是配置TZPC,并使用设置寄存器对其进行修改,使UART0处于安全状态下,无法被普通世界下的DEBIAN系统访问,直到输入‘a‘,切换回非安全状态,具体的各寄存器功能可以参见Hi6210sft的相关寄存器接口的功能介绍。

这篇关于HIKEY OP-TEE切换UART运行状态的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/960794

相关文章

如何用Docker运行Django项目

本章教程,介绍如何用Docker创建一个Django,并运行能够访问。 一、拉取镜像 这里我们使用python3.11版本的docker镜像 docker pull python:3.11 二、运行容器 这里我们将容器内部的8080端口,映射到宿主机的80端口上。 docker run -itd --name python311 -p

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

hdu1565(状态压缩)

本人第一道ac的状态压缩dp,这题的数据非常水,很容易过 题意:在n*n的矩阵中选数字使得不存在任意两个数字相邻,求最大值 解题思路: 一、因为在1<<20中有很多状态是无效的,所以第一步是选择有效状态,存到cnt[]数组中 二、dp[i][j]表示到第i行的状态cnt[j]所能得到的最大值,状态转移方程dp[i][j] = max(dp[i][j],dp[i-1][k]) ,其中k满足c

状态dp总结

zoj 3631  N 个数中选若干数和(只能选一次)<=M 的最大值 const int Max_N = 38 ;int a[1<<16] , b[1<<16] , x[Max_N] , e[Max_N] ;void GetNum(int g[] , int n , int s[] , int &m){ int i , j , t ;m = 0 ;for(i = 0 ;

hdu3006状态dp

给你n个集合。集合中均为数字且数字的范围在[1,m]内。m<=14。现在问用这些集合能组成多少个集合自己本身也算。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.Inp

跨系统环境下LabVIEW程序稳定运行

在LabVIEW开发中,不同电脑的配置和操作系统(如Win11与Win7)可能对程序的稳定运行产生影响。为了确保程序在不同平台上都能正常且稳定运行,需要从兼容性、驱动、以及性能优化等多个方面入手。本文将详细介绍如何在不同系统环境下,使LabVIEW开发的程序保持稳定运行的有效策略。 LabVIEW版本兼容性 LabVIEW各版本对不同操作系统的支持存在差异。因此,在开发程序时,尽量使用

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

实例:如何统计当前主机的连接状态和连接数

统计当前主机的连接状态和连接数 在 Linux 中,可使用 ss 命令来查看主机的网络连接状态。以下是统计当前主机连接状态和连接主机数量的具体操作。 1. 统计当前主机的连接状态 使用 ss 命令结合 grep、cut、sort 和 uniq 命令来统计当前主机的 TCP 连接状态。 ss -nta | grep -v '^State' | cut -d " " -f 1 | sort |

如何在运行时修改serialVersionUID

优质博文:IT-BLOG-CN 问题 我正在使用第三方库连接到外部系统,一切运行正常,但突然出现序列化错误 java.io.InvalidClassException: com.essbase.api.base.EssException; local class incompatible: stream classdesc serialVersionUID = 90314637791991

MyBatis 切换不同的类型数据库方案

下属案例例当前结合SpringBoot 配置进行讲解。 背景: 实现一个工程里面在部署阶段支持切换不同类型数据库支持。 方案一 数据源配置 关键代码(是什么数据库,该怎么配就怎么配) spring:datasource:name: test# 使用druid数据源type: com.alibaba.druid.pool.DruidDataSource# @需要修改 数据库连接及驱动u