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:
parent
a4858c40ec
commit
31a6594212
14 changed files with 101 additions and 37 deletions
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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++) {
|
||||||
|
|
||||||
|
|
17
dts/bindings/interrupt-controller/intel,loapic.yaml
Normal file
17
dts/bindings/interrupt-controller/intel,loapic.yaml
Normal 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
|
|
@ -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>;
|
||||||
|
|
|
@ -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>;
|
||||||
|
|
|
@ -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>;
|
||||||
|
|
|
@ -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>;
|
||||||
|
|
|
@ -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>;
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue