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
* 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 <offsets_short.h>
@ -197,10 +198,10 @@ alreadyOnIntStack:
wrmsr
#else /* xAPIC */
#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)
#else
movl %eax, (CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_EOI)
movl %eax, (LOAPIC_BASE_ADDRESS + LOAPIC_EOI)
#endif /* DEVICE_MMIO_IS_IN_RAM */
#endif /* CONFIG_X2APIC */

View file

@ -2,6 +2,7 @@
* Copyright (c) 2019 Intel Corporation
* SPDX-License-Identifier: Apache-2.0
*/
#define LOAPIC_BASE_ADDRESS DT_REG_ADDR(DT_NODELABEL(intc_loapic))
#include <zephyr/toolchain.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.
*/
movl CONFIG_LOAPIC_BASE_ADDRESS+LOAPIC_ID, %eax
movl LOAPIC_BASE_ADDRESS+LOAPIC_ID, %eax
shrl $24, %eax
andl $0x0F, %eax /* local APIC ID -> EAX */
@ -810,7 +811,7 @@ irq_dispatch:
movl $(X86_X2APIC_BASE_MSR + (LOAPIC_EOI >> 4)), %ecx
wrmsr
#else /* xAPIC */
movq z_loapic_regs, %rdx
movq Z_TOPLEVEL_RAM_NAME(LOAPIC_REGS_STR), %rdx
movl %eax, LOAPIC_EOI(%rdx)
#endif /* CONFIG_X2APIC */

View file

@ -9,12 +9,6 @@ menuconfig 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
bool "Access local APIC in x2APIC mode"
help

View file

@ -3,6 +3,9 @@
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT intel_loapic
/*
* driver for x86 CPU local APIC (as an interrupt controller)
*/
@ -59,18 +62,15 @@
#define LOAPIC_SPURIOUS_VECTOR_ID CONFIG_LOAPIC_SPURIOUS_VECTOR_ID
#endif
#define LOPIC_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_SSPND_BITS_PER_IRQ 1 /* Just the one for enable disable*/
#define LOAPIC_SUSPEND_BITS_REQD (ROUND_UP((LOAPIC_IRQ_COUNT * LOAPIC_SSPND_BITS_PER_IRQ), 32))
#ifdef CONFIG_PM_DEVICE
#include <zephyr/pm/device.h>
__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
#ifdef DEVICE_MMIO_IS_IN_RAM
__pinned_bss
mm_reg_t z_loapic_regs;
#endif
DEVICE_MMIO_TOPLEVEL(LOAPIC_REGS_STR, DT_DRV_INST(0));
__pinned_func
void send_eoi(void)
@ -87,11 +87,8 @@ __pinned_func
void z_loapic_enable(unsigned char cpu_number)
{
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
/*
* 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);
(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++) {

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;
};
intc_loapic: loapic@fee00000 {
compatible = "intel,loapic";
reg = <0xfee00000 0x1000>;
interrupt-controller;
#interrupt-cells = <3>;
#address-cells = <1>;
};
pcie0: pcie0 {
#address-cells = <1>;
#size-cells = <1>;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -28,6 +28,13 @@
#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
* configurations. So RAM and peripherals need to be

View file

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

View file

@ -49,12 +49,17 @@
#define LOAPIC_LVT_MASKED 0x00010000 /* mask */
/* Defined in intc_loapic.c */
#define LOAPIC_REGS_STR loapic_regs /* mmio device name */
#ifndef _ASMLANGUAGE
#ifdef __cplusplus
extern "C" {
#endif
DEVICE_MMIO_TOPLEVEL_DECLARE(LOAPIC_REGS_STR);
extern uint32_t z_loapic_irq_base(void);
extern void z_loapic_enable(unsigned char cpu_number);
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);
}
/* 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.
*
@ -85,11 +85,7 @@ extern mm_reg_t z_loapic_regs;
static inline uint32_t x86_read_xapic(unsigned int reg)
{
mm_reg_t base;
#ifdef DEVICE_MMIO_IS_IN_RAM
base = z_loapic_regs;
#else
base = CONFIG_LOAPIC_BASE_ADDRESS;
#endif
base = DEVICE_MMIO_TOPLEVEL_GET(LOAPIC_REGS_STR);
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)
{
mm_reg_t base;
#ifdef DEVICE_MMIO_IS_IN_RAM
base = z_loapic_regs;
#else
base = CONFIG_LOAPIC_BASE_ADDRESS;
#endif
base = DEVICE_MMIO_TOPLEVEL_GET(LOAPIC_REGS_STR);
sys_write32(val, base + reg);
}