optee os中的console driver

optee 中可以有自己的console来打印log,每个厂商必须实现自己的console driver,这里以D02为例
其code在core/arch/arm/plat-d02/main.c 中,所有注册给optee的console 必须调用register_serial_console,这种机制和kernel中的类似
static struct hi16xx_uart_data console_data __early_bss;

void console_init(void)
{
    hi16xx_uart_init(&console_data, CONSOLE_UART_BASE,
             CONSOLE_UART_CLK_IN_HZ, CONSOLE_BAUDRATE);
    register_serial_console(&console_data.chip);
}
在console_init中首先通过hi16xx_uart_init来初始化console_data.chip,最后调用register_serial_console来注册console

void hi16xx_uart_init(struct hi16xx_uart_data *pd, paddr_t base,
              uint32_t uart_clk, uint32_t baud_rate)
{
    uint16_t freq_div = uart_clk / (16 * baud_rate);

    pd->base.pa = base;
//给chip.ops 赋值,这个最重要。最后的对串口的读写最后都是通过chip.ops是实现。
    pd->chip.ops = &hi16xx_uart_ops;
//下面这些都有注释
    /* Enable (and clear) FIFOs */
    write32(UART_FCR_FIFO_EN, base + UART_FCR);

    /* Enable access to _DLL and _DLH */
    write32(UART_LCR_DLAB, base + UART_LCR);

    /* Calculate and set UART_DLL */
    write32(freq_div & 0xFF, base + UART_DLL);

    /* Calculate and set UART_DLH */
    write32((freq_div >> 8) & 0xFF, base + UART_DLH);

    /* Clear _DLL/_DLH access bit, set data size (8 bits), parity etc. */
    write32(UART_LCR_DLS8, base + UART_LCR);
//禁止中断,可见optee os中的console是通过poll的方式打印的
    /* Disable interrupt mode */
    write32(0, base + UART_IEL);
//通过写寄存器的方式flush 串口
    hi16xx_uart_flush(&pd->chip);
}

static const struct serial_ops hi16xx_uart_ops = {
    .flush = hi16xx_uart_flush,
    .getchar = hi16xx_uart_getchar,
    .have_rx_data = hi16xx_uart_have_rx_data,
    .putc = hi16xx_uart_putc,
};
这里以常用的putc为例
static void hi16xx_uart_putc(struct serial_chip *chip, int ch)
{
    vaddr_t base = chip_to_base(chip);

    /* Wait until TX FIFO is empty */
    while (!(read32(base + UART_USR) & UART_USR_TFE_BIT))
        ;

    /* Put character into TX FIFO */
    write32(ch & 0xFF, base + UART_THR);
}
原来就是通过写寄存器的方式输出字符。
回到console_init 中调用register_serial_console 来注册console
static struct serial_chip *serial_console __early_bss;

void __weak console_putc(int ch)
{
    if (!serial_console)
        return;

    if (ch == '\n')
        serial_console->ops->putc(serial_console, '\r');
    serial_console->ops->putc(serial_console, ch);
}

void __weak console_flush(void)
{
    if (!serial_console)
        return;

    serial_console->ops->flush(serial_console);
}

void register_serial_console(struct serial_chip *chip)
{
    serial_console = chip;
}
原来就是给静态变量serial_console 赋值,从register_serial_console 中也可以看出optee中的console只能有一个,如果register_serial_console 被调用多次的话,以最后一个的console为准
这样就可以在code中通过console_putc来打印log


但实际情况是我们并不能直接使用console_putc,而是外包了一层API
    if (tzc_id != TZC400_COMPONENT_ID) {
        EMSG("TZC : Wrong device ID (0x%x).\n", tzc_id);
        panic();
    }
例如错误信息就用EMSG
#if (TRACE_LEVEL <= 0)
#define MSG(...)   (void)0
#else
#define MSG(...)   trace_printf_helper(0, false, __VA_ARGS__)
#endif

/* Formatted trace tagged with TRACE_ERROR level */
#if (TRACE_LEVEL < TRACE_ERROR)
#define EMSG(...)   (void)0
#else
#define EMSG(...)   trace_printf_helper(TRACE_ERROR, true, __VA_ARGS__)
#endif

/* Formatted trace tagged with TRACE_INFO level */
#if (TRACE_LEVEL < TRACE_INFO)
#define IMSG(...)   (void)0
#else
#define IMSG(...)   trace_printf_helper(TRACE_INFO, true, __VA_ARGS__)
#endif
其他的级别如上,就是可以控制打印的级别
如果要改变打印的级别的话
#ifndef TRACE_LEVEL
#define TRACE_LEVEL TRACE_MAX
#endif
可以修改TRACE_LEVEL,这个值默认是最大,也就是一行log都不打印
这些最终都会调用trace_printf_helper
#define trace_printf_helper(level, level_ok, ...) \
    trace_printf(__func__, __LINE__, (level), (level_ok), \
             __VA_ARGS__)
trace_printf在通过snprintk格式话后最后调用trace_ext_puts显示log
void trace_ext_puts(const char *str)
{
    uint32_t itr_status = thread_mask_exceptions(THREAD_EXCP_ALL);
    bool mmu_enabled = cpu_mmu_enabled();
    bool was_contended = false;
    const char *p;

    if (mmu_enabled && !cpu_spin_trylock(&puts_lock)) {
        was_contended = true;
        cpu_spin_lock(&puts_lock);
    }

    console_flush();

    if (was_contended)
        console_putc('*');

    for (p = str; *p; p++)
        console_putc(*p);

    console_flush();

    if (mmu_enabled)
        cpu_spin_unlock(&puts_lock);

    thread_unmask_exceptions(itr_status);
}
可见在trace_ext_puts 中还是用我们之前的console_putc来打印
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值