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的相关寄存器接口的功能介绍。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值