[U-Boot] [PATCH v2 12/15] x86: Generate a valid MultiProcessor (MP) table
Bin Meng
bmeng.cn at gmail.com
Fri Jun 19 06:15:22 CEST 2015
On Thu, Jun 18, 2015 at 4:17 PM, Bin Meng <bmeng.cn at gmail.com> wrote:
> Implement write_mp_table() to create a minimal working MP table.
> This includes an MP floating table, a configuration table header
> and all of the 5 base configuration table entries. The I/O interrupt
> assignment table entry is created based on the same information used
> in the creation of PIRQ routing table from device tree. A check
> duplicated entry logic is applied to prevent writing multiple I/O
> interrupt entries with the same information.
>
> Use a Kconfig option GENERATE_MP_TABLE to tell U-Boot whether we
> need actually write the MP table at the F seg, just like we did for
> PIRQ routing and SFI tables. With MP table existence, linux kernel
> will switch to I/O APIC and local APIC to process all the peripheral
> interrupts instead of 8259 PICs. This takes full advantage of the
> multicore hardware and the SMP kernel.
>
> Signed-off-by: Bin Meng <bmeng.cn at gmail.com>
>
> ---
>
> Changes in v2:
> - Avoid using u16 and u8 in parameters
> - Add a comment block for check_dup_entry()
> - Return and check error codes of mptable_add_intsrc()
> - Remove __weak for write_mp_table()
>
[snip]
> +u32 write_mp_table(u32 addr)
> +{
> + struct mp_config_table *mc;
> + int ioapic_id, ioapic_ver;
> + int bus_isa = 0xff;
> + int ret;
> + u32 end;
> +
> + /* 16 byte align the table address */
> + addr = ALIGN(addr, 16);
> +
> + /* Write floating table */
> + mc = mp_write_floating_table((struct mp_floating_table *)addr);
> +
> + /* Write configuration table header */
> + mp_config_table_init(mc);
> +
> + /* Write processor entry */
> + mp_write_processor(mc);
> +
> + /* Write bus entry */
> + mp_write_bus(mc, bus_isa, BUSTYPE_ISA);
> +
> + /* Write I/O APIC entry */
> + ioapic_id = io_apic_read(IO_APIC_ID) >> 24;
> + ioapic_ver = io_apic_read(IO_APIC_VER) & 0xff;
> + mp_write_ioapic(mc, ioapic_id, ioapic_ver, IO_APIC_ADDR);
> +
> + /* Write I/O interrupt assignment entry */
> + ret = mptable_add_intsrc(mc, bus_isa, ioapic_id);
> + if (!ret)
Sorry, the logic is wrong here. Should be if (ret)
> + debug("Failed to write I/O interrupt assignment table\n");
> +
> + /* Write local interrupt assignment entry */
> + mptable_add_lintsrc(mc, bus_isa);
> +
> + /* Finalize the MP table */
> + end = mptable_finalize(mc);
> +
> + return end;
> +}
[snip]
Regards,
Bin
More information about the U-Boot
mailing list