diff options
author | Zheng Bao <zheng.bao@amd.com> | 2020-06-10 11:04:36 +0800 |
---|---|---|
committer | Felix Held <felix-coreboot@felixheld.de> | 2020-06-16 19:14:05 +0000 |
commit | aac79e0b8f4777f8a912ccdfc483755b7a4da52c (patch) | |
tree | 54a2642ee3a64727503285cde90dab136d95cd27 /src/cpu | |
parent | 49e0e0016892aeb04cde177323eaf085fbb8fbda (diff) |
x86/lapic: Set EXTINT on BSP only
When Linux is booted, the kernel reports
"do_IRQ: 1.55 No irq handler for vector"
So far it comes with payloads SeaBIOS and depthcharge, not with
Grub. We assume Grub does something to avoid this problem.
AMD bug tracker system (JIRA PLAT-21393) says the APs can not be set
EXTINT delivery mode.
In Intel 64 and IA-32 Architectures Software Developer’s Manual volume
3A, see chapter 10.5.1 Local Vector Table, it says:
"The APIC architecture supports only one ExtINT source in a system,
usually contained in the compatibility bridge. Only one processor in the
system should have an LVT entry configured to use the ExtINT delivery
mode."
Tested on mandolin (Picasso) board, the error in dmesg is gone.
The bug 153677727 has two parts.
1. Soft lockup
2. do_IRQ 1.55.
The soft lockup issued has been fixed by
https://review.coreboot.org/c/coreboot/+/41128
BUG=b:153677727
TEST=mandolin
Change-Id: I2956dcaad87cc1466deeca703748de33390b7603
Signed-off-by: Zheng Bao <zheng.bao@amd.com>
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/42219
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/cpu')
-rw-r--r-- | src/cpu/x86/lapic/lapic.c | 26 |
1 files changed, 11 insertions, 15 deletions
diff --git a/src/cpu/x86/lapic/lapic.c b/src/cpu/x86/lapic/lapic.c index f0a6cd7f46..653c3b2e40 100644 --- a/src/cpu/x86/lapic/lapic.c +++ b/src/cpu/x86/lapic/lapic.c @@ -2,16 +2,11 @@ #include <cpu/x86/lapic.h> #include <console/console.h> +#include <smp/node.h> void do_lapic_init(void) { - /* this is so interrupts work. This is very limited scope -- - * linux will do better later, we hope ... - */ - /* this is the first way we learned to do it. It fails on real SMP - * stuff. So we have to do things differently ... - * see the Intel mp1.4 spec, page A-3 - */ + uint32_t lvt0_val; printk(BIOS_INFO, "Setting up local APIC...\n"); @@ -28,15 +23,16 @@ void do_lapic_init(void) lapic_write_around(LAPIC_SPIV, (lapic_read_around(LAPIC_SPIV) & ~(LAPIC_VECTOR_MASK)) | LAPIC_SPIV_ENABLE); - lapic_write_around(LAPIC_LVT0, - (lapic_read_around(LAPIC_LVT0) & - ~(LAPIC_LVT_MASKED | LAPIC_LVT_LEVEL_TRIGGER | + + lvt0_val = (lapic_read_around(LAPIC_LVT0) & + ~(LAPIC_LVT_MASKED | LAPIC_LVT_LEVEL_TRIGGER | LAPIC_LVT_REMOTE_IRR | LAPIC_INPUT_POLARITY | - LAPIC_SEND_PENDING | LAPIC_LVT_RESERVED_1 | - LAPIC_DELIVERY_MODE_MASK)) - | (LAPIC_LVT_REMOTE_IRR | LAPIC_SEND_PENDING | - LAPIC_DELIVERY_MODE_EXTINT) - ); + LAPIC_SEND_PENDING | LAPIC_LVT_RESERVED_1)) | + (LAPIC_LVT_REMOTE_IRR | LAPIC_SEND_PENDING); + if (boot_cpu()) + lvt0_val = SET_LAPIC_DELIVERY_MODE(lvt0_val, LAPIC_MODE_EXINT); + lapic_write_around(LAPIC_LVT0, lvt0_val); + lapic_write_around(LAPIC_LVT1, (lapic_read_around(LAPIC_LVT1) & ~(LAPIC_LVT_MASKED | LAPIC_LVT_LEVEL_TRIGGER | |