drivers: loapic: add device tree support for loapic

As per #26393, Local APIC is using Kconfig based option for
the base address. This patch adds DTS binding support in the driver,
just like its conunter part I/O APIC.

Signed-off-by: Umar Nisar <umar.nisar@intel.com>
This commit is contained in:
Umar Nisar 2023-07-06 22:27:04 +02:00 committed by Carles Cufí
commit 31a6594212
14 changed files with 101 additions and 37 deletions

View file

@ -13,6 +13,7 @@
* exception) stubs are implemented in this module. The stubs are invoked when * exception) stubs are implemented in this module. The stubs are invoked when
* entering and exiting a C interrupt handler. * entering and exiting a C interrupt handler.
*/ */
#define LOAPIC_BASE_ADDRESS DT_REG_ADDR(DT_NODELABEL(intc_loapic))
#include <zephyr/arch/x86/ia32/asm.h> #include <zephyr/arch/x86/ia32/asm.h>
#include <offsets_short.h> #include <offsets_short.h>
@ -197,10 +198,10 @@ alreadyOnIntStack:
wrmsr wrmsr
#else /* xAPIC */ #else /* xAPIC */
#ifdef DEVICE_MMIO_IS_IN_RAM #ifdef DEVICE_MMIO_IS_IN_RAM
movl z_loapic_regs, %edx movl Z_TOPLEVEL_RAM_NAME(LOAPIC_REGS_STR), %edx
movl %eax, LOAPIC_EOI(%edx) movl %eax, LOAPIC_EOI(%edx)
#else #else
movl %eax, (CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_EOI) movl %eax, (LOAPIC_BASE_ADDRESS + LOAPIC_EOI)
#endif /* DEVICE_MMIO_IS_IN_RAM */ #endif /* DEVICE_MMIO_IS_IN_RAM */
#endif /* CONFIG_X2APIC */ #endif /* CONFIG_X2APIC */

View file

@ -2,6 +2,7 @@
* Copyright (c) 2019 Intel Corporation * Copyright (c) 2019 Intel Corporation
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#define LOAPIC_BASE_ADDRESS DT_REG_ADDR(DT_NODELABEL(intc_loapic))
#include <zephyr/toolchain.h> #include <zephyr/toolchain.h>
#include <zephyr/arch/x86/multiboot.h> #include <zephyr/arch/x86/multiboot.h>
@ -142,7 +143,7 @@ x86_ap_start:
* so we can locate our x86_cpuboot[] bundle. Put it in EBP. * so we can locate our x86_cpuboot[] bundle. Put it in EBP.
*/ */
movl CONFIG_LOAPIC_BASE_ADDRESS+LOAPIC_ID, %eax movl LOAPIC_BASE_ADDRESS+LOAPIC_ID, %eax
shrl $24, %eax shrl $24, %eax
andl $0x0F, %eax /* local APIC ID -> EAX */ andl $0x0F, %eax /* local APIC ID -> EAX */
@ -810,7 +811,7 @@ irq_dispatch:
movl $(X86_X2APIC_BASE_MSR + (LOAPIC_EOI >> 4)), %ecx movl $(X86_X2APIC_BASE_MSR + (LOAPIC_EOI >> 4)), %ecx
wrmsr wrmsr
#else /* xAPIC */ #else /* xAPIC */
movq z_loapic_regs, %rdx movq Z_TOPLEVEL_RAM_NAME(LOAPIC_REGS_STR), %rdx
movl %eax, LOAPIC_EOI(%rdx) movl %eax, LOAPIC_EOI(%rdx)
#endif /* CONFIG_X2APIC */ #endif /* CONFIG_X2APIC */

View file

@ -9,12 +9,6 @@ menuconfig LOAPIC
if LOAPIC if LOAPIC
config LOAPIC_BASE_ADDRESS
hex "Local APIC Base Address"
default 0xFEE00000
help
This option specifies the base address of the Local APIC device.
config X2APIC config X2APIC
bool "Access local APIC in x2APIC mode" bool "Access local APIC in x2APIC mode"
help help

View file

@ -3,6 +3,9 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#define DT_DRV_COMPAT intel_loapic
/* /*
* driver for x86 CPU local APIC (as an interrupt controller) * driver for x86 CPU local APIC (as an interrupt controller)
*/ */
@ -59,18 +62,15 @@
#define LOAPIC_SPURIOUS_VECTOR_ID CONFIG_LOAPIC_SPURIOUS_VECTOR_ID #define LOAPIC_SPURIOUS_VECTOR_ID CONFIG_LOAPIC_SPURIOUS_VECTOR_ID
#endif #endif
#define LOPIC_SSPND_BITS_PER_IRQ 1 /* Just the one for enable disable*/ #define LOAPIC_SSPND_BITS_PER_IRQ 1 /* Just the one for enable disable*/
#define LOPIC_SUSPEND_BITS_REQD (ROUND_UP((LOAPIC_IRQ_COUNT * LOPIC_SSPND_BITS_PER_IRQ), 32)) #define LOAPIC_SUSPEND_BITS_REQD (ROUND_UP((LOAPIC_IRQ_COUNT * LOAPIC_SSPND_BITS_PER_IRQ), 32))
#ifdef CONFIG_PM_DEVICE #ifdef CONFIG_PM_DEVICE
#include <zephyr/pm/device.h> #include <zephyr/pm/device.h>
__pinned_bss __pinned_bss
uint32_t loapic_suspend_buf[LOPIC_SUSPEND_BITS_REQD / 32] = {0}; uint32_t loapic_suspend_buf[LOAPIC_SUSPEND_BITS_REQD / 32] = {0};
#endif #endif
#ifdef DEVICE_MMIO_IS_IN_RAM DEVICE_MMIO_TOPLEVEL(LOAPIC_REGS_STR, DT_DRV_INST(0));
__pinned_bss
mm_reg_t z_loapic_regs;
#endif
__pinned_func __pinned_func
void send_eoi(void) void send_eoi(void)
@ -87,11 +87,8 @@ __pinned_func
void z_loapic_enable(unsigned char cpu_number) void z_loapic_enable(unsigned char cpu_number)
{ {
int32_t loApicMaxLvt; /* local APIC Max LVT */ int32_t loApicMaxLvt; /* local APIC Max LVT */
DEVICE_MMIO_TOPLEVEL_MAP(LOAPIC_REGS_STR, K_MEM_CACHE_NONE);
#ifdef DEVICE_MMIO_IS_IN_RAM
device_map(&z_loapic_regs, CONFIG_LOAPIC_BASE_ADDRESS, 0x1000,
K_MEM_CACHE_NONE);
#endif /* DEVICE_MMIO_IS_IN_RAM */
#ifndef CONFIG_X2APIC #ifndef CONFIG_X2APIC
/* /*
* in xAPIC and flat model, bits 24-31 in LDR (Logical APIC ID) are * in xAPIC and flat model, bits 24-31 in LDR (Logical APIC ID) are
@ -340,7 +337,7 @@ static int loapic_suspend(const struct device *port)
ARG_UNUSED(port); ARG_UNUSED(port);
(void)memset(loapic_suspend_buf, 0, (LOPIC_SUSPEND_BITS_REQD >> 3)); (void)memset(loapic_suspend_buf, 0, (LOAPIC_SUSPEND_BITS_REQD >> 3));
for (loapic_irq = 0; loapic_irq < LOAPIC_IRQ_COUNT; loapic_irq++) { for (loapic_irq = 0; loapic_irq < LOAPIC_IRQ_COUNT; loapic_irq++) {

View file

@ -0,0 +1,17 @@
description: Local Advanced Programmable Interrupt Controller (APIC)
compatible: "intel,loapic"
include: [interrupt-controller.yaml, base.yaml]
properties:
reg:
required: true
"#interrupt-cells":
const: 3
interrupt-cells:
- irq
- sense
- priority

View file

@ -37,6 +37,14 @@
interrupt-controller; interrupt-controller;
}; };
intc_loapic: loapic@fee00000 {
compatible = "intel,loapic";
reg = <0xfee00000 0x1000>;
interrupt-controller;
#interrupt-cells = <3>;
#address-cells = <1>;
};
pcie0: pcie0 { pcie0: pcie0 {
#address-cells = <1>; #address-cells = <1>;
#size-cells = <1>; #size-cells = <1>;

View file

@ -36,6 +36,14 @@
interrupt-controller; interrupt-controller;
}; };
intc_loapic: loapic@fee00000 {
compatible = "intel,loapic";
reg = <0xfee00000 0x1000>;
interrupt-controller;
#interrupt-cells = <3>;
#address-cells = <1>;
};
pcie0: pcie0 { pcie0: pcie0 {
#address-cells = <1>; #address-cells = <1>;
#size-cells = <1>; #size-cells = <1>;

View file

@ -32,6 +32,13 @@
#interrupt-cells = <3>; #interrupt-cells = <3>;
}; };
intc_loapic: loapic@fee00000 {
compatible = "intel,loapic";
reg = <0xfee00000 0x1000>;
interrupt-controller;
#interrupt-cells = <3>;
};
soc { soc {
#address-cells = <1>; #address-cells = <1>;
#size-cells = <1>; #size-cells = <1>;

View file

@ -41,6 +41,14 @@
interrupt-controller; interrupt-controller;
}; };
intc_loapic: loapic@fee00000 {
compatible = "intel,loapic";
reg = <0xfee00000 0x1000>;
interrupt-controller;
#interrupt-cells = <3>;
#address-cells = <1>;
};
pcie0: pcie0 { pcie0: pcie0 {
#address-cells = <1>; #address-cells = <1>;
#size-cells = <1>; #size-cells = <1>;

View file

@ -29,6 +29,14 @@
interrupt-controller; interrupt-controller;
}; };
intc_loapic: loapic@fee00000 {
compatible = "intel,loapic";
reg = <0xfee00000 0x1000>;
interrupt-controller;
#interrupt-cells = <3>;
#address-cells = <1>;
};
dram0: memory@0 { dram0: memory@0 {
device_type = "memory"; device_type = "memory";
reg = <DT_DRAM_BASE DT_DRAM_SIZE>; reg = <DT_DRAM_BASE DT_DRAM_SIZE>;

View file

@ -60,6 +60,14 @@
interrupt-controller; interrupt-controller;
}; };
intc_loapic: loapic@fee00000 {
compatible = "intel,loapic";
reg = <0xfee00000 0x1000>;
interrupt-controller;
#interrupt-cells = <3>;
#address-cells = <1>;
};
sram: memory@ff200000 { sram: memory@ff200000 {
device_type = "memory"; device_type = "memory";
compatible = "mmio-sram"; compatible = "mmio-sram";

View file

@ -28,6 +28,13 @@
#interrupt-cells = <3>; #interrupt-cells = <3>;
}; };
intc_loapic: loapic@fee00000 {
compatible = "intel,loapic";
reg = <0xfee00000 0x1000>;
interrupt-controller;
#interrupt-cells = <3>;
};
/* /*
* Platforms with Lakemont SoC can have different hardware * Platforms with Lakemont SoC can have different hardware
* configurations. So RAM and peripherals need to be * configurations. So RAM and peripherals need to be

View file

@ -36,6 +36,14 @@
interrupt-controller; interrupt-controller;
}; };
intc_loapic: loapic@fee00000 {
compatible = "intel,loapic";
reg = <0xfee00000 0x1000>;
interrupt-controller;
#interrupt-cells = <3>;
#address-cells = <1>;
};
pcie0: pcie0 { pcie0: pcie0 {
#address-cells = <1>; #address-cells = <1>;
#size-cells = <1>; #size-cells = <1>;

View file

@ -49,12 +49,17 @@
#define LOAPIC_LVT_MASKED 0x00010000 /* mask */ #define LOAPIC_LVT_MASKED 0x00010000 /* mask */
/* Defined in intc_loapic.c */
#define LOAPIC_REGS_STR loapic_regs /* mmio device name */
#ifndef _ASMLANGUAGE #ifndef _ASMLANGUAGE
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
DEVICE_MMIO_TOPLEVEL_DECLARE(LOAPIC_REGS_STR);
extern uint32_t z_loapic_irq_base(void); extern uint32_t z_loapic_irq_base(void);
extern void z_loapic_enable(unsigned char cpu_number); extern void z_loapic_enable(unsigned char cpu_number);
extern void z_loapic_int_vec_set(unsigned int irq, unsigned int vector); extern void z_loapic_int_vec_set(unsigned int irq, unsigned int vector);
@ -72,11 +77,6 @@ static inline uint64_t x86_read_x2apic(unsigned int reg)
return z_x86_msr_read(X86_X2APIC_BASE_MSR + reg); return z_x86_msr_read(X86_X2APIC_BASE_MSR + reg);
} }
/* Defined in intc_loapic.c */
#ifdef DEVICE_MMIO_IS_IN_RAM
extern mm_reg_t z_loapic_regs;
#endif
/** /**
* @brief Read 32-bit value from the local APIC in xAPIC (MMIO) mode. * @brief Read 32-bit value from the local APIC in xAPIC (MMIO) mode.
* *
@ -85,11 +85,7 @@ extern mm_reg_t z_loapic_regs;
static inline uint32_t x86_read_xapic(unsigned int reg) static inline uint32_t x86_read_xapic(unsigned int reg)
{ {
mm_reg_t base; mm_reg_t base;
#ifdef DEVICE_MMIO_IS_IN_RAM base = DEVICE_MMIO_TOPLEVEL_GET(LOAPIC_REGS_STR);
base = z_loapic_regs;
#else
base = CONFIG_LOAPIC_BASE_ADDRESS;
#endif
return sys_read32(base + reg); return sys_read32(base + reg);
} }
@ -133,11 +129,7 @@ static inline void x86_write_x2apic(unsigned int reg, uint64_t val)
static inline void x86_write_xapic(unsigned int reg, uint32_t val) static inline void x86_write_xapic(unsigned int reg, uint32_t val)
{ {
mm_reg_t base; mm_reg_t base;
#ifdef DEVICE_MMIO_IS_IN_RAM base = DEVICE_MMIO_TOPLEVEL_GET(LOAPIC_REGS_STR);
base = z_loapic_regs;
#else
base = CONFIG_LOAPIC_BASE_ADDRESS;
#endif
sys_write32(val, base + reg); sys_write32(val, base + reg);
} }