acpi 表中对spcr的parse来初始化串口

来源:互联网 发布:怎么用u盘导出考勤数据 编辑:程序博客网 时间:2024/06/16 13:18
在acpi_boot_table_init 中会调用parse_spcr 来从SPCR表中parse console参数,这就不用通过在cmdline中传递了。
这个函数首先acpi_get_table_with_size 得到SPCR,然后根据table->interface_type 得到iotype。再根据table->baud_rate得到波特率。
int __init parse_spcr(bool earlycon)
{


    status = acpi_get_table_with_size(ACPI_SIG_SPCR, 0,
                      (struct acpi_table_header **)&table,
                  &table_size);


    switch (table->interface_type) {
    case ACPI_DBG2_ARM_SBSA_32BIT:
        iotype = "mmio32";
        /* fall through */
    case ACPI_DBG2_ARM_PL011:
    case ACPI_DBG2_ARM_SBSA_GENERIC:
    case ACPI_DBG2_BCM2835:
        uart = "pl011";
        break;
    case ACPI_DBG2_16550_COMPATIBLE:
    case ACPI_DBG2_16550_SUBSET:
        if (table->serial_port.space_id ==
            ACPI_ADR_SPACE_SYSTEM_MEMORY &&
            table->serial_port.bit_width == 32)
            iotype = "mmio32";
        uart = "uart";
        break;
    default:
        err = -ENOENT;
        goto done;
    }

    switch (table->baud_rate) {
    case 3:
        baud_rate = 9600;
        break;
    case 4:
        baud_rate = 19200;
        break;
    case 6:
        baud_rate = 57600;
        break;
    case 7:
        baud_rate = 115200;
        break;
    default:
        err = -ENOENT;
        goto done;
    }

    snprintf(opts, sizeof(opts), "%s,%s,0x%llx,%d", uart, iotype,
         table->serial_port.address, baud_rate);

    pr_info("console: %s\n", opts);

    if (earlycon)
        setup_earlycon(opts);

    err = add_preferred_console(uart, 0, opts + strlen(uart) + 1);

done:
    early_acpi_os_unmap_memory((void __iomem *)table, table_size);
    return err;
}
最后通过snprintf来客制化opts。如果有定义earlycon的话,调用setup_earlycon来初始化earlycon。最后调用add_preferred_console来设置串口
add_preferred_console->__add_preferred_console
static int __add_preferred_console(char *name, int idx, char *options,
                   char *brl_options)
{
    struct console_cmdline *c;
    int i;

    /*
     *    See if this tty is not yet registered, and
     *    if we have a slot free.
     */
    for (i = 0, c = console_cmdline;
         i < MAX_CMDLINECONSOLES && c->name[0];
         i++, c++) {
        if (strcmp(c->name, name) == 0 && c->index == idx) {
            if (!brl_options)
                selected_console = i;
            return 0;
        }
    }
    if (i == MAX_CMDLINECONSOLES)
        return -E2BIG;
    if (!brl_options)
        selected_console = i;
    strlcpy(c->name, name, sizeof(c->name));
    c->options = options;
    braille_set_options(c, brl_options);

    c->index = idx;
    return 0;
}
最后在__add_preferred_console函数中比较console_cmdline 这个数组中已经注册的console和apci表传递过来的表中的name像比较,如果相等的话,就给selected_console赋值,表示用这个来串口来输出log
0 0