天天看點

acpi 表中對spcr的parse來初始化序列槽

在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";

    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;

    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