This patch series enables the basic ACPI infrastructure for RISC-V.
Supporting external interrupt controllers is in progress and hence it is
tested using poll based HVC SBI console and RAM disk.
The first patch in this series is one of the patch from Jisheng's
series [1] which is not merged yet. This patch is required to support
ACPI since efi_init() which gets called before sbi_init() can enable
static branches and hits a panic.
Patch 2 and 3 are ACPICA patches which are not merged into acpica yet
but a PR is raised already.
Below are two ECRs approved by ASWG.
RINTC - https://drive.google.com/file/d/1R6k4MshhN3WTT-hwqAquu5nX6xSEqK2l/view
RHCT - https://drive.google.com/file/d/1nP3nFiH4jkPMp6COOxP6123DCZKR-tia/view
The series depends on Anup's IPI improvement series [2].
[1] https://lore.kernel.org/all/[email protected]/
[2] https://lore.kernel.org/lkml/[email protected]/T/
Changes since V2:
1) Dropped ACPI_PROCESSOR patch.
2) Added new patch to print debug info of RISC-V INTC in MADT
3) Addressed other comments from Drew.
4) Rebased and updated tags
Changes since V1:
1) Dropped PCI changes and instead added dummy interfaces just to enable
building ACPI core when CONFIG_PCI is enabled. Actual PCI changes will
be added in future along with external interrupt controller support
in ACPI.
2) Squashed couple of patches so that new code added gets built in each
commit.
3) Fixed the missing wake_cpu code in timer refactor patch as pointed by
Conor
4) Fixed an issue with SMP disabled.
5) Addressed other comments from Conor.
6) Updated documentation patch as per feedback from Sanjaya.
7) Fixed W=1 and checkpatch --strict issues.
8) Added ACK/RB tags
These changes are available at
https://github.com/vlsunil/linux/commits/acpi_b1_us_review_ipi17_V3
Testing:
1) Build Qemu with ACPI support using below branch
https://github.com/vlsunil/qemu/tree/acpi_b1_us_review_V5
2) Build EDK2 as per instructions in
https://github.com/vlsunil/riscv-uefi-edk2-docs/wiki/RISC-V-Qemu-Virt-support
3) Build Linux after enabling SBI HVC and SBI earlycon
CONFIG_RISCV_SBI_V01=y
CONFIG_SERIAL_EARLYCON_RISCV_SBI=y
CONFIG_HVC_RISCV_SBI=y
4) Build buildroot.
Run with below command.
qemu-system-riscv64 -nographic \
-drive file=Build/RiscVVirtQemu/RELEASE_GCC5/FV/RISCV_VIRT.fd,if=pflash,format=raw,unit=1 \
-machine virt -smp 16 -m 2G \
-kernel arch/riscv/boot/Image \
-initrd buildroot/output/images/rootfs.cpio \
-append "root=/dev/ram ro console=hvc0 earlycon=sbi"
Jisheng Zhang (1):
riscv: move sbi_init() earlier before jump_label_init()
Sunil V L (19):
ACPICA: MADT: Add RISC-V INTC interrupt controller
ACPICA: Add structure definitions for RISC-V RHCT
ACPI: tables: Print RINTC information when MADT is parsed
ACPI: OSL: Make should_use_kmap() 0 for RISC-V
RISC-V: Add support to build the ACPI core
ACPI: processor_core: RISC-V: Enable mapping processor to the hartid
drivers/acpi: RISC-V: Add RHCT related code
RISC-V: smpboot: Create wrapper smp_setup()
RISC-V: smpboot: Add ACPI support in smp_setup()
RISC-V: ACPI: Cache and retrieve the RINTC structure
RISC-V: cpufeature: Add ACPI support in riscv_fill_hwcap()
RISC-V: cpu: Enable cpuinfo for ACPI systems
irqchip/riscv-intc: Add ACPI support
clocksource/timer-riscv: Refactor riscv_timer_init_dt()
clocksource/timer-riscv: Add ACPI support
RISC-V: time.c: Add ACPI support for time_init()
RISC-V: Add ACPI initialization in setup_arch()
RISC-V: Enable ACPI in defconfig
MAINTAINERS: Add entry for drivers/acpi/riscv
.../admin-guide/kernel-parameters.txt | 8 +-
MAINTAINERS | 8 +
arch/riscv/Kconfig | 5 +
arch/riscv/configs/defconfig | 1 +
arch/riscv/include/asm/acenv.h | 11 +
arch/riscv/include/asm/acpi.h | 82 ++++++
arch/riscv/include/asm/cpu.h | 8 +
arch/riscv/kernel/Makefile | 2 +
arch/riscv/kernel/acpi.c | 262 ++++++++++++++++++
arch/riscv/kernel/cpu.c | 27 +-
arch/riscv/kernel/cpufeature.c | 41 ++-
arch/riscv/kernel/setup.c | 27 +-
arch/riscv/kernel/smpboot.c | 77 ++++-
arch/riscv/kernel/time.c | 23 +-
drivers/acpi/Makefile | 2 +
drivers/acpi/osl.c | 2 +-
drivers/acpi/processor_core.c | 29 ++
drivers/acpi/riscv/Makefile | 2 +
drivers/acpi/riscv/rhct.c | 82 ++++++
drivers/acpi/tables.c | 10 +
drivers/clocksource/timer-riscv.c | 92 +++---
drivers/irqchip/irq-riscv-intc.c | 77 ++++-
include/acpi/actbl2.h | 68 ++++-
23 files changed, 854 insertions(+), 92 deletions(-)
create mode 100644 arch/riscv/include/asm/acenv.h
create mode 100644 arch/riscv/include/asm/acpi.h
create mode 100644 arch/riscv/include/asm/cpu.h
create mode 100644 arch/riscv/kernel/acpi.c
create mode 100644 drivers/acpi/riscv/Makefile
create mode 100644 drivers/acpi/riscv/rhct.c
--
2.34.1
From: Jisheng Zhang <[email protected]>
We call jump_label_init() in setup_arch() is to use static key
mechanism earlier, but riscv jump label relies on the sbi functions,
If we enable static key before sbi_init(), the code path looks like:
static_branch_enable()
..
arch_jump_label_transform()
patch_text_nosync()
flush_icache_range()
flush_icache_all()
sbi_remote_fence_i() for CONFIG_RISCV_SBI case
__sbi_rfence()
Since sbi isn't initialized, so NULL deference! Here is a typical
panic log:
[ 0.000000] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
[ 0.000000] Oops [#1]
[ 0.000000] Modules linked in:
[ 0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 5.18.0-rc7+ #79
[ 0.000000] Hardware name: riscv-virtio,qemu (DT)
[ 0.000000] epc : 0x0
[ 0.000000] ra : sbi_remote_fence_i+0x1e/0x26
[ 0.000000] epc : 0000000000000000 ra : ffffffff80005826 sp : ffffffff80c03d50
[ 0.000000] gp : ffffffff80ca6178 tp : ffffffff80c0ad80 t0 : 6200000000000000
[ 0.000000] t1 : 0000000000000000 t2 : 62203a6b746e6972 s0 : ffffffff80c03d60
[ 0.000000] s1 : ffffffff80001af6 a0 : 0000000000000000 a1 : 0000000000000000
[ 0.000000] a2 : 0000000000000000 a3 : 0000000000000000 a4 : 0000000000000000
[ 0.000000] a5 : 0000000000000000 a6 : 0000000000000000 a7 : 0000000000080200
[ 0.000000] s2 : ffffffff808b3e48 s3 : ffffffff808bf698 s4 : ffffffff80cb2818
[ 0.000000] s5 : 0000000000000001 s6 : ffffffff80c9c345 s7 : ffffffff80895aa0
[ 0.000000] s8 : 0000000000000001 s9 : 000000000000007f s10: 0000000000000000
[ 0.000000] s11: 0000000000000000 t3 : ffffffff80824d08 t4 : 0000000000000022
[ 0.000000] t5 : 000000000000003d t6 : 0000000000000000
[ 0.000000] status: 0000000000000100 badaddr: 0000000000000000 cause: 000000000000000c
[ 0.000000] ---[ end trace 0000000000000000 ]---
[ 0.000000] Kernel panic - not syncing: Attempted to kill the idle task!
[ 0.000000] ---[ end Kernel panic - not syncing: Attempted to kill the idle task! ]---
Fix this issue by moving sbi_init() earlier before jump_label_init()
Signed-off-by: Jisheng Zhang <[email protected]>
Reviewed-by: Anup Patel <[email protected]>
Reviewed-by: Atish Patra <[email protected]>
---
arch/riscv/kernel/setup.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
index 376d2827e736..2d45a416d283 100644
--- a/arch/riscv/kernel/setup.c
+++ b/arch/riscv/kernel/setup.c
@@ -270,6 +270,7 @@ void __init setup_arch(char **cmdline_p)
*cmdline_p = boot_command_line;
early_ioremap_setup();
+ sbi_init();
jump_label_init();
parse_early_param();
@@ -287,7 +288,6 @@ void __init setup_arch(char **cmdline_p)
misc_mem_init();
init_resources();
- sbi_init();
#ifdef CONFIG_KASAN
kasan_init();
--
2.34.1
The ECR to add RISC-V INTC interrupt controller is approved by
the UEFI forum and will be available in the next revision of
the ACPI specification.
This patch is not yet merged in ACPICA but a PR is raised.
ACPICA PR: https://github.com/acpica/acpica/pull/804
Reference: Mantis ID: 2348
Cc: Robert Moore <[email protected]>
Cc: [email protected]
Signed-off-by: Sunil V L <[email protected]>
Acked-by: Rafael J. Wysocki <[email protected]>
---
include/acpi/actbl2.h | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h
index b2973dbe37ee..abb700d246df 100644
--- a/include/acpi/actbl2.h
+++ b/include/acpi/actbl2.h
@@ -891,7 +891,8 @@ enum acpi_madt_type {
ACPI_MADT_TYPE_MSI_PIC = 21,
ACPI_MADT_TYPE_BIO_PIC = 22,
ACPI_MADT_TYPE_LPC_PIC = 23,
- ACPI_MADT_TYPE_RESERVED = 24, /* 24 to 0x7F are reserved */
+ ACPI_MADT_TYPE_RINTC = 24,
+ ACPI_MADT_TYPE_RESERVED = 25, /* 25 to 0x7F are reserved */
ACPI_MADT_TYPE_OEM_RESERVED = 0x80 /* 0x80 to 0xFF are reserved for OEM use */
};
@@ -1250,6 +1251,24 @@ enum acpi_madt_lpc_pic_version {
ACPI_MADT_LPC_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
};
+/* 24: RISC-V INTC */
+struct acpi_madt_rintc {
+ struct acpi_subtable_header header;
+ u8 version;
+ u8 reserved;
+ u32 flags;
+ u64 hart_id;
+ u32 uid; /* ACPI processor UID */
+};
+
+/* Values for RISC-V INTC Version field above */
+
+enum acpi_madt_rintc_version {
+ ACPI_MADT_RINTC_VERSION_NONE = 0,
+ ACPI_MADT_RINTC_VERSION_V1 = 1,
+ ACPI_MADT_RINTC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
+};
+
/* 80: OEM data */
struct acpi_madt_oem_data {
--
2.34.1
RISC-V Hart Capabilities Table (RHCT) is a new static table.
The ECR to add RHCT is approved by the UEFI forum and will be
available in the next version of the ACPI spec.
This patch is not yet merged in ACPICA but a PR is raised.
ACPICA PR: https://github.com/acpica/acpica/pull/804
Reference: Mantis: 2349
Cc: Robert Moore <[email protected]>
Cc: [email protected]
Signed-off-by: Sunil V L <[email protected]>
Acked-by: Rafael J. Wysocki <[email protected]>
---
include/acpi/actbl2.h | 47 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h
index abb700d246df..0715e937a453 100644
--- a/include/acpi/actbl2.h
+++ b/include/acpi/actbl2.h
@@ -47,6 +47,7 @@
#define ACPI_SIG_PRMT "PRMT" /* Platform Runtime Mechanism Table */
#define ACPI_SIG_RASF "RASF" /* RAS Feature table */
#define ACPI_SIG_RGRT "RGRT" /* Regulatory Graphics Resource Table */
+#define ACPI_SIG_RHCT "RHCT" /* RISC-V Hart Capabilities Table */
#define ACPI_SIG_SBST "SBST" /* Smart Battery Specification Table */
#define ACPI_SIG_SDEI "SDEI" /* Software Delegated Exception Interface Table */
#define ACPI_SIG_SDEV "SDEV" /* Secure Devices table */
@@ -2606,6 +2607,52 @@ enum acpi_rgrt_image_type {
/*******************************************************************************
*
+ * RHCT - RISC-V Hart Capabilities Table
+ * Version 1
+ *
+ ******************************************************************************/
+
+struct acpi_table_rhct {
+ struct acpi_table_header header; /* Common ACPI table header */
+ u32 reserved;
+ u64 time_base_freq;
+ u32 node_count;
+ u32 node_offset;
+};
+
+/*
+ * RHCT subtables
+ */
+struct acpi_rhct_node_header {
+ u16 type;
+ u16 length;
+ u16 revision;
+};
+
+/* Values for RHCT subtable Type above */
+
+enum acpi_rhct_node_type {
+ ACPI_RHCT_NODE_TYPE_ISA_STRING = 0x0000,
+ ACPI_RHCT_NODE_TYPE_HART_INFO = 0xFFFF,
+};
+
+/*
+ * RHCT node specific subtables
+ */
+
+/* ISA string node structure */
+struct acpi_rhct_isa_string {
+ u16 isa_length;
+ char isa[];
+};
+
+/* Hart Info node structure */
+struct acpi_rhct_hart_info {
+ u16 num_offsets;
+ u32 uid; /* ACPI processor UID */
+};
+
+/*******************************************************************************
* SBST - Smart Battery Specification Table
* Version 1
*
--
2.34.1
When MADT is parsed, print RINTC information as below:
ACPI: RISC-V INTC (acpi_uid[0x0000] hart_id[0x0] enabled)
ACPI: RISC-V INTC (acpi_uid[0x0001] hart_id[0x1] enabled)
...
ACPI: RISC-V INTC (acpi_uid[0x000f] hart_id[0xf] enabled)
This debug information will be very helpful during bring up.
Signed-off-by: Sunil V L <[email protected]>
Acked-by: Rafael J. Wysocki <[email protected]>
---
drivers/acpi/tables.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 7b4680da57d7..8ab0a82b4da4 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -220,6 +220,16 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
}
break;
+ case ACPI_MADT_TYPE_RINTC:
+ {
+ struct acpi_madt_rintc *p = (struct acpi_madt_rintc *)header;
+
+ pr_debug("RISC-V INTC (acpi_uid[0x%04x] hart_id[0x%llx] %s)\n",
+ p->uid, p->hart_id,
+ (p->flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
+ }
+ break;
+
default:
pr_warn("Found unsupported MADT entry (type = 0x%x)\n",
header->type);
--
2.34.1
Without this, if the tables are larger than 4K,
acpi_map() will fail.
Signed-off-by: Sunil V L <[email protected]>
Acked-by: Rafael J. Wysocki <[email protected]>
---
drivers/acpi/osl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 3269a888fb7a..f725813d0cce 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -276,7 +276,7 @@ acpi_map_lookup_virt(void __iomem *virt, acpi_size size)
return NULL;
}
-#if defined(CONFIG_IA64) || defined(CONFIG_ARM64)
+#if defined(CONFIG_IA64) || defined(CONFIG_ARM64) || defined(CONFIG_RISCV)
/* ioremap will take care of cache attributes */
#define should_use_kmap(pfn) 0
#else
--
2.34.1
Enable ACPI core for RISC-V after adding architecture-specific
interfaces and header files required to build the ACPI core.
1) Couple of header files are required unconditionally by the ACPI
core. Add empty acenv.h and cpu.h header files.
2) If CONFIG_PCI is enabled, a few PCI related interfaces need to
be provided by the architecture. Define dummy interfaces for now
so that build succeeds. Actual implementation will be added when
PCI support is added for ACPI along with external interrupt
controller support.
3) A few globals and memory mapping related functions specific
to the architecture need to be provided.
Signed-off-by: Sunil V L <[email protected]>
Acked-by: Rafael J. Wysocki <[email protected]>
Reviewed-by: Andrew Jones <[email protected]>
---
arch/riscv/Kconfig | 5 +++
arch/riscv/include/asm/acenv.h | 11 +++++
arch/riscv/include/asm/acpi.h | 61 ++++++++++++++++++++++++++
arch/riscv/include/asm/cpu.h | 8 ++++
arch/riscv/kernel/Makefile | 2 +
arch/riscv/kernel/acpi.c | 80 ++++++++++++++++++++++++++++++++++
6 files changed, 167 insertions(+)
create mode 100644 arch/riscv/include/asm/acenv.h
create mode 100644 arch/riscv/include/asm/acpi.h
create mode 100644 arch/riscv/include/asm/cpu.h
create mode 100644 arch/riscv/kernel/acpi.c
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 71754eb32ee6..f3108c7e19d8 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -12,6 +12,8 @@ config 32BIT
config RISCV
def_bool y
+ select ACPI_GENERIC_GSI if ACPI
+ select ACPI_REDUCED_HARDWARE_ONLY if ACPI
select ARCH_ENABLE_HUGEPAGE_MIGRATION if HUGETLB_PAGE && MIGRATION
select ARCH_ENABLE_SPLIT_PMD_PTLOCK if PGTABLE_LEVELS > 2
select ARCH_ENABLE_THP_MIGRATION if TRANSPARENT_HUGEPAGE
@@ -617,6 +619,7 @@ config EFI
depends on OF && !XIP_KERNEL
depends on MMU
default y
+ select ARCH_SUPPORTS_ACPI if 64BIT
select EFI_GENERIC_STUB
select EFI_PARAMS_FROM_FDT
select EFI_RUNTIME_WRAPPERS
@@ -720,3 +723,5 @@ source "drivers/cpufreq/Kconfig"
endmenu # "CPU Power Management"
source "arch/riscv/kvm/Kconfig"
+
+source "drivers/acpi/Kconfig"
diff --git a/arch/riscv/include/asm/acenv.h b/arch/riscv/include/asm/acenv.h
new file mode 100644
index 000000000000..22123c5a4883
--- /dev/null
+++ b/arch/riscv/include/asm/acenv.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * RISC-V specific ACPICA environments and implementation
+ */
+
+#ifndef _ASM_ACENV_H
+#define _ASM_ACENV_H
+
+/* It is required unconditionally by ACPI core */
+
+#endif /* _ASM_ACENV_H */
diff --git a/arch/riscv/include/asm/acpi.h b/arch/riscv/include/asm/acpi.h
new file mode 100644
index 000000000000..0b52a190f71a
--- /dev/null
+++ b/arch/riscv/include/asm/acpi.h
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2013-2014, Linaro Ltd.
+ * Author: Al Stone <[email protected]>
+ * Author: Graeme Gregory <[email protected]>
+ * Author: Hanjun Guo <[email protected]>
+ *
+ * Copyright (C) 2021-2023, Ventana Micro Systems Inc.
+ * Author: Sunil V L <[email protected]>
+ */
+
+#ifndef _ASM_ACPI_H
+#define _ASM_ACPI_H
+
+/* Basic configuration for ACPI */
+#ifdef CONFIG_ACPI
+
+/* ACPI table mapping after acpi_permanent_mmap is set */
+void *acpi_os_ioremap(acpi_physical_address phys, acpi_size size);
+#define acpi_os_ioremap acpi_os_ioremap
+
+#define acpi_strict 1 /* No out-of-spec workarounds on RISC-V */
+extern int acpi_disabled;
+extern int acpi_noirq;
+extern int acpi_pci_disabled;
+
+static inline void disable_acpi(void)
+{
+ acpi_disabled = 1;
+ acpi_pci_disabled = 1;
+ acpi_noirq = 1;
+}
+
+static inline void enable_acpi(void)
+{
+ acpi_disabled = 0;
+ acpi_pci_disabled = 0;
+ acpi_noirq = 0;
+}
+
+/*
+ * The ACPI processor driver for ACPI core code needs this macro
+ * to find out this cpu was already mapped (mapping from CPU hardware
+ * ID to CPU logical ID) or not.
+ */
+#define cpu_physical_id(cpu) cpuid_to_hartid_map(cpu)
+
+/*
+ * Since MADT must provide at least one RINTC structure, the
+ * CPU will be always available in MADT on RISC-V.
+ */
+static inline bool acpi_has_cpu_in_madt(void)
+{
+ return true;
+}
+
+static inline void arch_fix_phys_package_id(int num, u32 slot) { }
+
+#endif /* CONFIG_ACPI */
+
+#endif /*_ASM_ACPI_H*/
diff --git a/arch/riscv/include/asm/cpu.h b/arch/riscv/include/asm/cpu.h
new file mode 100644
index 000000000000..ea1a88b3d5f2
--- /dev/null
+++ b/arch/riscv/include/asm/cpu.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _ASM_CPU_H
+#define _ASM_CPU_H
+
+/* It is required unconditionally by ACPI core */
+
+#endif /* _ASM_CPU_H */
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 67f542be1bea..f979dc8cf47d 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -90,3 +90,5 @@ obj-$(CONFIG_EFI) += efi.o
obj-$(CONFIG_COMPAT) += compat_syscall_table.o
obj-$(CONFIG_COMPAT) += compat_signal.o
obj-$(CONFIG_COMPAT) += compat_vdso/
+
+obj-$(CONFIG_ACPI) += acpi.o
diff --git a/arch/riscv/kernel/acpi.c b/arch/riscv/kernel/acpi.c
new file mode 100644
index 000000000000..81d448c41714
--- /dev/null
+++ b/arch/riscv/kernel/acpi.c
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * RISC-V Specific Low-Level ACPI Boot Support
+ *
+ * Copyright (C) 2013-2014, Linaro Ltd.
+ * Author: Al Stone <[email protected]>
+ * Author: Graeme Gregory <[email protected]>
+ * Author: Hanjun Guo <[email protected]>
+ * Author: Tomasz Nowicki <[email protected]>
+ * Author: Naresh Bhat <[email protected]>
+ *
+ * Copyright (C) 2021-2023, Ventana Micro Systems Inc.
+ * Author: Sunil V L <[email protected]>
+ */
+
+#include <linux/acpi.h>
+#include <linux/io.h>
+#include <linux/pci.h>
+
+int acpi_noirq = 1; /* skip ACPI IRQ initialization */
+int acpi_disabled = 1;
+EXPORT_SYMBOL(acpi_disabled);
+
+int acpi_pci_disabled = 1; /* skip ACPI PCI scan and IRQ initialization */
+EXPORT_SYMBOL(acpi_pci_disabled);
+
+/*
+ * __acpi_map_table() will be called before paging_init(), so early_ioremap()
+ * or early_memremap() should be called here to for ACPI table mapping.
+ */
+void __init __iomem *__acpi_map_table(unsigned long phys, unsigned long size)
+{
+ if (!size)
+ return NULL;
+
+ return early_memremap(phys, size);
+}
+
+void __init __acpi_unmap_table(void __iomem *map, unsigned long size)
+{
+ if (!map || !size)
+ return;
+
+ early_memunmap(map, size);
+}
+
+void *acpi_os_ioremap(acpi_physical_address phys, acpi_size size)
+{
+ return memremap(phys, size, MEMREMAP_WB);
+}
+
+#ifdef CONFIG_PCI
+
+/*
+ * These interfaces are defined just to enable building ACPI core.
+ * TODO: Update it with actual implementation when external interrupt
+ * controller support is added in RISC-V ACPI.
+ */
+int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn,
+ int reg, int len, u32 *val)
+{
+ return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+int raw_pci_write(unsigned int domain, unsigned int bus, unsigned int devfn,
+ int reg, int len, u32 val)
+{
+ return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+int acpi_pci_bus_find_domain_nr(struct pci_bus *bus)
+{
+ return -1;
+}
+
+struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
+{
+ return NULL;
+}
+#endif /* CONFIG_PCI */
--
2.34.1
processor_core needs arch-specific functions to map the ACPI ID
to the physical ID. In RISC-V platforms, hartid is the physical id
and RINTC structure in MADT provides this mapping. Add arch-specific
function to get this mapping from RINTC.
Signed-off-by: Sunil V L <[email protected]>
Acked-by: Rafael J. Wysocki <[email protected]>
Reviewed-by: Andrew Jones <[email protected]>
---
arch/riscv/include/asm/acpi.h | 3 +++
drivers/acpi/processor_core.c | 29 +++++++++++++++++++++++++++++
2 files changed, 32 insertions(+)
diff --git a/arch/riscv/include/asm/acpi.h b/arch/riscv/include/asm/acpi.h
index 0b52a190f71a..7671c401f4ec 100644
--- a/arch/riscv/include/asm/acpi.h
+++ b/arch/riscv/include/asm/acpi.h
@@ -15,6 +15,9 @@
/* Basic configuration for ACPI */
#ifdef CONFIG_ACPI
+typedef u64 phys_cpuid_t;
+#define PHYS_CPUID_INVALID INVALID_HARTID
+
/* ACPI table mapping after acpi_permanent_mmap is set */
void *acpi_os_ioremap(acpi_physical_address phys, acpi_size size);
#define acpi_os_ioremap acpi_os_ioremap
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 2ac48cda5b20..d6606a9f2da6 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -106,6 +106,32 @@ static int map_gicc_mpidr(struct acpi_subtable_header *entry,
return -EINVAL;
}
+/*
+ * Retrieve the RISC-V hartid for the processor
+ */
+static int map_rintc_hartid(struct acpi_subtable_header *entry,
+ int device_declaration, u32 acpi_id,
+ phys_cpuid_t *hartid)
+{
+ struct acpi_madt_rintc *rintc =
+ container_of(entry, struct acpi_madt_rintc, header);
+
+ if (!(rintc->flags & ACPI_MADT_ENABLED))
+ return -ENODEV;
+
+ /* device_declaration means Device object in DSDT, in the
+ * RISC-V, logical processors are required to
+ * have a Processor Device object in the DSDT, so we should
+ * check device_declaration here
+ */
+ if (device_declaration && rintc->uid == acpi_id) {
+ *hartid = rintc->hart_id;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
static phys_cpuid_t map_madt_entry(struct acpi_table_madt *madt,
int type, u32 acpi_id)
{
@@ -136,6 +162,9 @@ static phys_cpuid_t map_madt_entry(struct acpi_table_madt *madt,
} else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) {
if (!map_gicc_mpidr(header, type, acpi_id, &phys_id))
break;
+ } else if (header->type == ACPI_MADT_TYPE_RINTC) {
+ if (!map_rintc_hartid(header, type, acpi_id, &phys_id))
+ break;
}
entry += header->length;
}
--
2.34.1
smp_setup() currently assumes DT-based platforms. To enable ACPI,
first make this a wrapper function and move existing code to
a separate DT-specific function.
Signed-off-by: Sunil V L <[email protected]>
Acked-by: Rafael J. Wysocki <[email protected]>
Reviewed-by: Conor Dooley <[email protected]>
Reviewed-by: Andrew Jones <[email protected]>
---
arch/riscv/kernel/smpboot.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c
index 00b53913d4c6..26214ddefaa4 100644
--- a/arch/riscv/kernel/smpboot.c
+++ b/arch/riscv/kernel/smpboot.c
@@ -70,7 +70,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
}
}
-void __init setup_smp(void)
+static void __init of_parse_and_init_cpus(void)
{
struct device_node *dn;
unsigned long hart;
@@ -116,6 +116,11 @@ void __init setup_smp(void)
}
}
+void __init setup_smp(void)
+{
+ of_parse_and_init_cpus();
+}
+
static int start_secondary_cpu(int cpu, struct task_struct *tidle)
{
if (cpu_ops[cpu]->cpu_start)
--
2.34.1
RHCT is a new table defined for RISC-V to communicate the
features of the CPU to the OS. Create a new architecture folder
in drivers/acpi and add RHCT parsing code.
Signed-off-by: Sunil V L <[email protected]>
Acked-by: Rafael J. Wysocki <[email protected]>
Reviewed-by: Andrew Jones <[email protected]>
---
arch/riscv/include/asm/acpi.h | 9 ++++
drivers/acpi/Makefile | 2 +
drivers/acpi/riscv/Makefile | 2 +
drivers/acpi/riscv/rhct.c | 82 +++++++++++++++++++++++++++++++++++
4 files changed, 95 insertions(+)
create mode 100644 drivers/acpi/riscv/Makefile
create mode 100644 drivers/acpi/riscv/rhct.c
diff --git a/arch/riscv/include/asm/acpi.h b/arch/riscv/include/asm/acpi.h
index 7671c401f4ec..111a8ed10af1 100644
--- a/arch/riscv/include/asm/acpi.h
+++ b/arch/riscv/include/asm/acpi.h
@@ -59,6 +59,15 @@ static inline bool acpi_has_cpu_in_madt(void)
static inline void arch_fix_phys_package_id(int num, u32 slot) { }
+int acpi_get_riscv_isa(struct acpi_table_header *table,
+ unsigned int cpu, const char **isa);
+#else
+static inline int acpi_get_riscv_isa(struct acpi_table_header *table,
+ unsigned int cpu, const char **isa)
+{
+ return -EINVAL;
+}
+
#endif /* CONFIG_ACPI */
#endif /*_ASM_ACPI_H*/
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index feb36c0b9446..3fc5a0d54f6e 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -131,3 +131,5 @@ obj-y += dptf/
obj-$(CONFIG_ARM64) += arm64/
obj-$(CONFIG_ACPI_VIOT) += viot.o
+
+obj-$(CONFIG_RISCV) += riscv/
diff --git a/drivers/acpi/riscv/Makefile b/drivers/acpi/riscv/Makefile
new file mode 100644
index 000000000000..8b3b126e0b94
--- /dev/null
+++ b/drivers/acpi/riscv/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-y += rhct.o
diff --git a/drivers/acpi/riscv/rhct.c b/drivers/acpi/riscv/rhct.c
new file mode 100644
index 000000000000..2e2aeb7cae49
--- /dev/null
+++ b/drivers/acpi/riscv/rhct.c
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022-2023, Ventana Micro Systems Inc
+ * Author: Sunil V L <[email protected]>
+ *
+ */
+
+#define pr_fmt(fmt) "ACPI: RHCT: " fmt
+
+#include <linux/acpi.h>
+
+static struct acpi_table_header *acpi_get_rhct(void)
+{
+ static struct acpi_table_header *rhct;
+ acpi_status status;
+
+ /*
+ * RHCT will be used at runtime on every CPU, so we
+ * don't need to call acpi_put_table() to release the table mapping.
+ */
+ if (!rhct) {
+ status = acpi_get_table(ACPI_SIG_RHCT, 0, &rhct);
+ if (ACPI_FAILURE(status)) {
+ pr_warn_once("No RHCT table found\n");
+ return NULL;
+ }
+ }
+
+ return rhct;
+}
+
+/*
+ * During early boot, the caller should call acpi_get_table() and pass its pointer to
+ * these functions(and free up later). At run time, since this table can be used
+ * multiple times, NULL may be passed in order to use the cached table.
+ */
+int acpi_get_riscv_isa(struct acpi_table_header *table, unsigned int acpi_cpu_id, const char **isa)
+{
+ struct acpi_rhct_node_header *node, *ref_node, *end;
+ u32 size_hdr = sizeof(struct acpi_rhct_node_header);
+ u32 size_hartinfo = sizeof(struct acpi_rhct_hart_info);
+ struct acpi_rhct_hart_info *hart_info;
+ struct acpi_rhct_isa_string *isa_node;
+ struct acpi_table_rhct *rhct;
+ u32 *hart_info_node_offset;
+
+ BUG_ON(acpi_disabled);
+
+ if (!table) {
+ rhct = (struct acpi_table_rhct *)acpi_get_rhct();
+ if (!rhct)
+ return -ENOENT;
+ } else {
+ rhct = (struct acpi_table_rhct *)table;
+ }
+
+ end = ACPI_ADD_PTR(struct acpi_rhct_node_header, rhct, rhct->header.length);
+
+ for (node = ACPI_ADD_PTR(struct acpi_rhct_node_header, rhct, rhct->node_offset);
+ node < end;
+ node = ACPI_ADD_PTR(struct acpi_rhct_node_header, node, node->length)) {
+ if (node->type == ACPI_RHCT_NODE_TYPE_HART_INFO) {
+ hart_info = ACPI_ADD_PTR(struct acpi_rhct_hart_info, node, size_hdr);
+ hart_info_node_offset = ACPI_ADD_PTR(u32, hart_info, size_hartinfo);
+ if (acpi_cpu_id != hart_info->uid)
+ continue;
+
+ for (int i = 0; i < hart_info->num_offsets; i++) {
+ ref_node = ACPI_ADD_PTR(struct acpi_rhct_node_header,
+ rhct, hart_info_node_offset[i]);
+ if (ref_node->type == ACPI_RHCT_NODE_TYPE_ISA_STRING) {
+ isa_node = ACPI_ADD_PTR(struct acpi_rhct_isa_string,
+ ref_node, size_hdr);
+ *isa = isa_node->isa;
+ return 0;
+ }
+ }
+ }
+ }
+
+ return -1;
+}
--
2.34.1
Enable SMP boot on ACPI based platforms by using the RINTC
structures in the MADT table.
Signed-off-by: Sunil V L <[email protected]>
Acked-by: Rafael J. Wysocki <[email protected]>
Reviewed-by: Conor Dooley <[email protected]>
---
arch/riscv/kernel/smpboot.c | 72 ++++++++++++++++++++++++++++++++++++-
1 file changed, 71 insertions(+), 1 deletion(-)
diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c
index 26214ddefaa4..27047322d3bb 100644
--- a/arch/riscv/kernel/smpboot.c
+++ b/arch/riscv/kernel/smpboot.c
@@ -8,6 +8,7 @@
* Copyright (C) 2017 SiFive
*/
+#include <linux/acpi.h>
#include <linux/arch_topology.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -70,6 +71,72 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
}
}
+#ifdef CONFIG_ACPI
+static unsigned int cpu_count = 1;
+
+static int __init acpi_parse_rintc(union acpi_subtable_headers *header, const unsigned long end)
+{
+ unsigned long hart;
+ static bool found_boot_cpu;
+ struct acpi_madt_rintc *processor = (struct acpi_madt_rintc *)header;
+
+ /*
+ * Each RINTC structure in MADT will have a flag. If ACPI_MADT_ENABLED
+ * bit in the flag is not enabled, it means OS should not try to enable
+ * the cpu to which RINTC belongs.
+ */
+ if (!(processor->flags & ACPI_MADT_ENABLED))
+ return 0;
+
+ if (BAD_MADT_ENTRY(processor, end))
+ return -EINVAL;
+
+ acpi_table_print_madt_entry(&header->common);
+
+ hart = processor->hart_id;
+ if (hart == INVALID_HARTID) {
+ pr_warn("Invalid hartid\n");
+ return 0;
+ }
+
+ if (hart == cpuid_to_hartid_map(0)) {
+ BUG_ON(found_boot_cpu);
+ found_boot_cpu = true;
+ early_map_cpu_to_node(0, NUMA_NO_NODE);
+ return 0;
+ }
+
+ if (cpu_count >= NR_CPUS) {
+ pr_warn("NR_CPUS is too small for the number of ACPI tables.\n");
+ return 0;
+ }
+
+ cpuid_to_hartid_map(cpu_count) = hart;
+ early_map_cpu_to_node(cpu_count, NUMA_NO_NODE);
+ cpu_count++;
+
+ return 0;
+}
+
+static void __init acpi_parse_and_init_cpus(void)
+{
+ int cpuid;
+
+ cpu_set_ops(0);
+
+ acpi_table_parse_madt(ACPI_MADT_TYPE_RINTC, acpi_parse_rintc, 0);
+
+ for (cpuid = 1; cpuid < nr_cpu_ids; cpuid++) {
+ if (cpuid_to_hartid_map(cpuid) != INVALID_HARTID) {
+ cpu_set_ops(cpuid);
+ set_cpu_possible(cpuid, true);
+ }
+ }
+}
+#else
+#define acpi_parse_and_init_cpus(...) do { } while (0)
+#endif
+
static void __init of_parse_and_init_cpus(void)
{
struct device_node *dn;
@@ -118,7 +185,10 @@ static void __init of_parse_and_init_cpus(void)
void __init setup_smp(void)
{
- of_parse_and_init_cpus();
+ if (acpi_disabled)
+ of_parse_and_init_cpus();
+ else
+ acpi_parse_and_init_cpus();
}
static int start_secondary_cpu(int cpu, struct task_struct *tidle)
--
2.34.1
RINTC structures in the MADT provide mapping between the hartid
and the CPU. This is required many times even at run time like
cpuinfo. So, instead of parsing the ACPI table every time, cache
the RINTC structures and provide a function to get the correct
RINTC structure for a given cpu.
Signed-off-by: Sunil V L <[email protected]>
Acked-by: Rafael J. Wysocki <[email protected]>
---
arch/riscv/include/asm/acpi.h | 9 ++++++
arch/riscv/kernel/acpi.c | 56 +++++++++++++++++++++++++++++++++++
2 files changed, 65 insertions(+)
diff --git a/arch/riscv/include/asm/acpi.h b/arch/riscv/include/asm/acpi.h
index 111a8ed10af1..8be16c1ef7da 100644
--- a/arch/riscv/include/asm/acpi.h
+++ b/arch/riscv/include/asm/acpi.h
@@ -61,6 +61,10 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
int acpi_get_riscv_isa(struct acpi_table_header *table,
unsigned int cpu, const char **isa);
+
+struct acpi_madt_rintc *acpi_cpu_get_madt_rintc(int cpu);
+
+u32 get_acpi_id_for_cpu(int cpu);
#else
static inline int acpi_get_riscv_isa(struct acpi_table_header *table,
unsigned int cpu, const char **isa)
@@ -68,6 +72,11 @@ static inline int acpi_get_riscv_isa(struct acpi_table_header *table,
return -EINVAL;
}
+static inline u32 get_acpi_id_for_cpu(int cpu)
+{
+ return -1;
+}
+
#endif /* CONFIG_ACPI */
#endif /*_ASM_ACPI_H*/
diff --git a/arch/riscv/kernel/acpi.c b/arch/riscv/kernel/acpi.c
index 81d448c41714..8b3d68d8225f 100644
--- a/arch/riscv/kernel/acpi.c
+++ b/arch/riscv/kernel/acpi.c
@@ -24,6 +24,62 @@ EXPORT_SYMBOL(acpi_disabled);
int acpi_pci_disabled = 1; /* skip ACPI PCI scan and IRQ initialization */
EXPORT_SYMBOL(acpi_pci_disabled);
+static struct acpi_madt_rintc cpu_madt_rintc[NR_CPUS];
+
+static int acpi_parse_madt_rintc(union acpi_subtable_headers *header, const unsigned long end)
+{
+ struct acpi_madt_rintc *rintc = (struct acpi_madt_rintc *)header;
+ int cpuid;
+
+ if (!(rintc->flags & ACPI_MADT_ENABLED))
+ return 0;
+
+ cpuid = riscv_hartid_to_cpuid(rintc->hart_id);
+ if (cpuid >= 0 && cpuid < NR_CPUS)
+ cpu_madt_rintc[cpuid] = *rintc;
+
+ return 0;
+}
+
+static int acpi_init_rintc_array(void)
+{
+ if (acpi_table_parse_madt(ACPI_MADT_TYPE_RINTC, acpi_parse_madt_rintc, 0) > 0)
+ return 0;
+
+ return -ENODEV;
+}
+
+/*
+ * Instead of parsing (and freeing) the ACPI table, cache
+ * the RINTC structures since they are frequently used
+ * like in cpuinfo.
+ */
+struct acpi_madt_rintc *acpi_cpu_get_madt_rintc(int cpu)
+{
+ static bool rintc_init_done;
+
+ if (!rintc_init_done) {
+ if (acpi_init_rintc_array()) {
+ pr_err("No valid RINTC entries exist\n");
+ return NULL;
+ }
+
+ rintc_init_done = true;
+ }
+
+ return &cpu_madt_rintc[cpu];
+}
+
+u32 get_acpi_id_for_cpu(int cpu)
+{
+ struct acpi_madt_rintc *rintc = acpi_cpu_get_madt_rintc(cpu);
+
+ if (!rintc)
+ return -1;
+
+ return rintc->uid;
+}
+
/*
* __acpi_map_table() will be called before paging_init(), so early_ioremap()
* or early_memremap() should be called here to for ACPI table mapping.
--
2.34.1
On ACPI based systems, the information about the hart
like ISA is provided by the RISC-V Hart Capabilities Table (RHCT).
Enable filling up hwcap structure based on the information in RHCT.
Signed-off-by: Sunil V L <[email protected]>
Acked-by: Rafael J. Wysocki <[email protected]>
---
arch/riscv/kernel/cpufeature.c | 41 ++++++++++++++++++++++++++--------
1 file changed, 32 insertions(+), 9 deletions(-)
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index 59d58ee0f68d..478dbf129922 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -6,6 +6,7 @@
* Copyright (C) 2017 SiFive
*/
+#include <linux/acpi.h>
#include <linux/bitmap.h>
#include <linux/ctype.h>
#include <linux/libfdt.h>
@@ -13,6 +14,8 @@
#include <linux/memory.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_device.h>
+#include <asm/acpi.h>
#include <asm/alternative.h>
#include <asm/cacheflush.h>
#include <asm/errata_list.h>
@@ -91,7 +94,9 @@ void __init riscv_fill_hwcap(void)
char print_str[NUM_ALPHA_EXTS + 1];
int i, j, rc;
unsigned long isa2hwcap[26] = {0};
- unsigned long hartid;
+ struct acpi_table_header *rhct;
+ acpi_status status;
+ unsigned int cpu;
isa2hwcap['i' - 'a'] = COMPAT_HWCAP_ISA_I;
isa2hwcap['m' - 'a'] = COMPAT_HWCAP_ISA_M;
@@ -104,18 +109,33 @@ void __init riscv_fill_hwcap(void)
bitmap_zero(riscv_isa, RISCV_ISA_EXT_MAX);
- for_each_of_cpu_node(node) {
+ if (!acpi_disabled) {
+ status = acpi_get_table(ACPI_SIG_RHCT, 0, &rhct);
+ if (ACPI_FAILURE(status))
+ return;
+ }
+
+ for_each_possible_cpu(cpu) {
unsigned long this_hwcap = 0;
DECLARE_BITMAP(this_isa, RISCV_ISA_EXT_MAX);
const char *temp;
- rc = riscv_of_processor_hartid(node, &hartid);
- if (rc < 0)
- continue;
-
- if (of_property_read_string(node, "riscv,isa", &isa)) {
- pr_warn("Unable to find \"riscv,isa\" devicetree entry\n");
- continue;
+ if (acpi_disabled) {
+ node = of_cpu_device_node_get(cpu);
+ if (node) {
+ rc = of_property_read_string(node, "riscv,isa", &isa);
+ of_node_put(node);
+ if (rc) {
+ pr_warn("Unable to find \"riscv,isa\" devicetree entry\n");
+ continue;
+ }
+ }
+ } else {
+ rc = acpi_get_riscv_isa(rhct, get_acpi_id_for_cpu(cpu), &isa);
+ if (rc < 0) {
+ pr_warn("Unable to get ISA for the hart - %d\n", cpu);
+ continue;
+ }
}
temp = isa;
@@ -248,6 +268,9 @@ void __init riscv_fill_hwcap(void)
bitmap_and(riscv_isa, riscv_isa, this_isa, RISCV_ISA_EXT_MAX);
}
+ if (!acpi_disabled && rhct)
+ acpi_put_table((struct acpi_table_header *)rhct);
+
/* We don't support systems with F but without D, so mask those out
* here. */
if ((elf_hwcap & COMPAT_HWCAP_ISA_F) && !(elf_hwcap & COMPAT_HWCAP_ISA_D)) {
--
2.34.1
On ACPI based platforms, few details like ISA need to be read
from the ACPI table. Enable cpuinfo on ACPI based systems.
Signed-off-by: Sunil V L <[email protected]>
Acked-by: Rafael J. Wysocki <[email protected]>
---
arch/riscv/kernel/cpu.c | 27 +++++++++++++++++++--------
1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
index 8400f0cc9704..80101bf77dab 100644
--- a/arch/riscv/kernel/cpu.c
+++ b/arch/riscv/kernel/cpu.c
@@ -3,10 +3,12 @@
* Copyright (C) 2012 Regents of the University of California
*/
+#include <linux/acpi.h>
#include <linux/cpu.h>
#include <linux/init.h>
#include <linux/seq_file.h>
#include <linux/of.h>
+#include <asm/acpi.h>
#include <asm/csr.h>
#include <asm/hwcap.h>
#include <asm/sbi.h>
@@ -283,23 +285,32 @@ static void c_stop(struct seq_file *m, void *v)
static int c_show(struct seq_file *m, void *v)
{
unsigned long cpu_id = (unsigned long)v - 1;
- struct device_node *node = of_get_cpu_node(cpu_id, NULL);
struct riscv_cpuinfo *ci = per_cpu_ptr(&riscv_cpuinfo, cpu_id);
+ struct device_node *node;
const char *compat, *isa;
seq_printf(m, "processor\t: %lu\n", cpu_id);
seq_printf(m, "hart\t\t: %lu\n", cpuid_to_hartid_map(cpu_id));
- if (!of_property_read_string(node, "riscv,isa", &isa))
- print_isa(m, isa);
- print_mmu(m);
- if (!of_property_read_string(node, "compatible", &compat)
- && strcmp(compat, "riscv"))
- seq_printf(m, "uarch\t\t: %s\n", compat);
+
+ if (acpi_disabled) {
+ node = of_get_cpu_node(cpu_id, NULL);
+ if (!of_property_read_string(node, "riscv,isa", &isa))
+ print_isa(m, isa);
+ print_mmu(m);
+ if (!of_property_read_string(node, "compatible", &compat) &&
+ strcmp(compat, "riscv"))
+ seq_printf(m, "uarch\t\t: %s\n", compat);
+ of_node_put(node);
+ } else {
+ if (!acpi_get_riscv_isa(NULL, get_acpi_id_for_cpu(cpu_id), &isa))
+ print_isa(m, isa);
+ print_mmu(m);
+ }
+
seq_printf(m, "mvendorid\t: 0x%lx\n", ci->mvendorid);
seq_printf(m, "marchid\t\t: 0x%lx\n", ci->marchid);
seq_printf(m, "mimpid\t\t: 0x%lx\n", ci->mimpid);
seq_puts(m, "\n");
- of_node_put(node);
return 0;
}
--
2.34.1
Add support for initializing the RISC-V INTC driver on ACPI
platforms.
Signed-off-by: Sunil V L <[email protected]>
Acked-by: Rafael J. Wysocki <[email protected]>
Reviewed-by: Andrew Jones <[email protected]>
---
drivers/irqchip/irq-riscv-intc.c | 77 +++++++++++++++++++++++++++-----
1 file changed, 65 insertions(+), 12 deletions(-)
diff --git a/drivers/irqchip/irq-riscv-intc.c b/drivers/irqchip/irq-riscv-intc.c
index f229e3e66387..f522510dc1f3 100644
--- a/drivers/irqchip/irq-riscv-intc.c
+++ b/drivers/irqchip/irq-riscv-intc.c
@@ -6,6 +6,7 @@
*/
#define pr_fmt(fmt) "riscv-intc: " fmt
+#include <linux/acpi.h>
#include <linux/atomic.h>
#include <linux/bits.h>
#include <linux/cpu.h>
@@ -112,6 +113,30 @@ static struct fwnode_handle *riscv_intc_hwnode(void)
return intc_domain->fwnode;
}
+static int __init riscv_intc_init_common(struct fwnode_handle *fn)
+{
+ int rc;
+
+ intc_domain = irq_domain_create_linear(fn, BITS_PER_LONG,
+ &riscv_intc_domain_ops, NULL);
+ if (!intc_domain) {
+ pr_err("unable to add IRQ domain\n");
+ return -ENXIO;
+ }
+
+ rc = set_handle_irq(&riscv_intc_irq);
+ if (rc) {
+ pr_err("failed to set irq handler\n");
+ return rc;
+ }
+
+ riscv_set_intc_hwnode_fn(riscv_intc_hwnode);
+
+ pr_info("%d local interrupts mapped\n", BITS_PER_LONG);
+
+ return 0;
+}
+
static int __init riscv_intc_init(struct device_node *node,
struct device_node *parent)
{
@@ -133,24 +158,52 @@ static int __init riscv_intc_init(struct device_node *node,
if (riscv_hartid_to_cpuid(hartid) != smp_processor_id())
return 0;
- intc_domain = irq_domain_add_linear(node, BITS_PER_LONG,
- &riscv_intc_domain_ops, NULL);
- if (!intc_domain) {
- pr_err("unable to add IRQ domain\n");
- return -ENXIO;
- }
-
- rc = set_handle_irq(&riscv_intc_irq);
+ rc = riscv_intc_init_common(of_node_to_fwnode(node));
if (rc) {
- pr_err("failed to set irq handler\n");
+ pr_err("failed to initialize INTC\n");
return rc;
}
- riscv_set_intc_hwnode_fn(riscv_intc_hwnode);
+ return 0;
+}
- pr_info("%d local interrupts mapped\n", BITS_PER_LONG);
+IRQCHIP_DECLARE(riscv, "riscv,cpu-intc", riscv_intc_init);
+
+#ifdef CONFIG_ACPI
+
+static int __init riscv_intc_acpi_init(union acpi_subtable_headers *header,
+ const unsigned long end)
+{
+ int rc;
+ struct fwnode_handle *fn;
+ struct acpi_madt_rintc *rintc;
+
+ rintc = (struct acpi_madt_rintc *)header;
+
+ /*
+ * The ACPI MADT will have one INTC for each CPU (or HART)
+ * so riscv_intc_acpi_init() function will be called once
+ * for each INTC. We only do INTC initialization
+ * for the INTC belonging to the boot CPU (or boot HART).
+ */
+ if (riscv_hartid_to_cpuid(rintc->hart_id) != smp_processor_id())
+ return 0;
+
+ fn = irq_domain_alloc_named_fwnode("RISCV-INTC");
+ if (!fn) {
+ pr_err("unable to allocate INTC FW node\n");
+ return -ENOMEM;
+ }
+
+ rc = riscv_intc_init_common(fn);
+ if (rc) {
+ pr_err("failed to initialize INTC\n");
+ return rc;
+ }
return 0;
}
-IRQCHIP_DECLARE(riscv, "riscv,cpu-intc", riscv_intc_init);
+IRQCHIP_ACPI_DECLARE(riscv_intc, ACPI_MADT_TYPE_RINTC, NULL,
+ ACPI_MADT_RINTC_VERSION_V1, riscv_intc_acpi_init);
+#endif
--
2.34.1
Refactor the timer init function such that few things can be
shared by both DT and ACPI based platforms.
Co-developed-by: Anup Patel <[email protected]>
Signed-off-by: Anup Patel <[email protected]>
Signed-off-by: Sunil V L <[email protected]>
Acked-by: Rafael J. Wysocki <[email protected]>
Reviewed-by: Andrew Jones <[email protected]>
---
drivers/clocksource/timer-riscv.c | 81 +++++++++++++++----------------
1 file changed, 40 insertions(+), 41 deletions(-)
diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c
index 5f0f10c7e222..cecc4662293b 100644
--- a/drivers/clocksource/timer-riscv.c
+++ b/drivers/clocksource/timer-riscv.c
@@ -124,61 +124,28 @@ static irqreturn_t riscv_timer_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int __init riscv_timer_init_dt(struct device_node *n)
+static int __init riscv_timer_init_common(void)
{
- int cpuid, error;
- unsigned long hartid;
- struct device_node *child;
+ int error;
struct irq_domain *domain;
+ struct fwnode_handle *intc_fwnode = riscv_get_intc_hwnode();
- error = riscv_of_processor_hartid(n, &hartid);
- if (error < 0) {
- pr_warn("Not valid hartid for node [%pOF] error = [%lu]\n",
- n, hartid);
- return error;
- }
-
- cpuid = riscv_hartid_to_cpuid(hartid);
- if (cpuid < 0) {
- pr_warn("Invalid cpuid for hartid [%lu]\n", hartid);
- return cpuid;
- }
-
- if (cpuid != smp_processor_id())
- return 0;
-
- child = of_find_compatible_node(NULL, NULL, "riscv,timer");
- if (child) {
- riscv_timer_cannot_wake_cpu = of_property_read_bool(child,
- "riscv,timer-cannot-wake-cpu");
- of_node_put(child);
- }
-
- domain = NULL;
- child = of_get_compatible_child(n, "riscv,cpu-intc");
- if (!child) {
- pr_err("Failed to find INTC node [%pOF]\n", n);
- return -ENODEV;
- }
- domain = irq_find_host(child);
- of_node_put(child);
+ domain = irq_find_matching_fwnode(intc_fwnode, DOMAIN_BUS_ANY);
if (!domain) {
- pr_err("Failed to find IRQ domain for node [%pOF]\n", n);
+ pr_err("Failed to find irq_domain for INTC node [%pfwP]\n",
+ intc_fwnode);
return -ENODEV;
}
riscv_clock_event_irq = irq_create_mapping(domain, RV_IRQ_TIMER);
if (!riscv_clock_event_irq) {
- pr_err("Failed to map timer interrupt for node [%pOF]\n", n);
+ pr_err("Failed to map timer interrupt for node [%pfwP]\n", intc_fwnode);
return -ENODEV;
}
- pr_info("%s: Registering clocksource cpuid [%d] hartid [%lu]\n",
- __func__, cpuid, hartid);
error = clocksource_register_hz(&riscv_clocksource, riscv_timebase);
if (error) {
- pr_err("RISCV timer register failed [%d] for cpu = [%d]\n",
- error, cpuid);
+ pr_err("RISCV timer registration failed [%d]\n", error);
return error;
}
@@ -207,4 +174,36 @@ static int __init riscv_timer_init_dt(struct device_node *n)
return error;
}
+static int __init riscv_timer_init_dt(struct device_node *n)
+{
+ int cpuid, error;
+ unsigned long hartid;
+ struct device_node *child;
+
+ error = riscv_of_processor_hartid(n, &hartid);
+ if (error < 0) {
+ pr_warn("Invalid hartid for node [%pOF] error = [%lu]\n",
+ n, hartid);
+ return error;
+ }
+
+ cpuid = riscv_hartid_to_cpuid(hartid);
+ if (cpuid < 0) {
+ pr_warn("Invalid cpuid for hartid [%lu]\n", hartid);
+ return cpuid;
+ }
+
+ if (cpuid != smp_processor_id())
+ return 0;
+
+ child = of_find_compatible_node(NULL, NULL, "riscv,timer");
+ if (child) {
+ riscv_timer_cannot_wake_cpu = of_property_read_bool(child,
+ "riscv,timer-cannot-wake-cpu");
+ of_node_put(child);
+ }
+
+ return riscv_timer_init_common();
+}
+
TIMER_OF_DECLARE(riscv_timer, "riscv", riscv_timer_init_dt);
--
2.34.1
Initialize the timer driver based on RHCT table on ACPI based
platforms.
Signed-off-by: Sunil V L <[email protected]>
Acked-by: Rafael J. Wysocki <[email protected]>
Reviewed-by: Andrew Jones <[email protected]>
---
drivers/clocksource/timer-riscv.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c
index cecc4662293b..da3071b387eb 100644
--- a/drivers/clocksource/timer-riscv.c
+++ b/drivers/clocksource/timer-riscv.c
@@ -10,6 +10,7 @@
#define pr_fmt(fmt) "riscv-timer: " fmt
+#include <linux/acpi.h>
#include <linux/clocksource.h>
#include <linux/clockchips.h>
#include <linux/cpu.h>
@@ -207,3 +208,13 @@ static int __init riscv_timer_init_dt(struct device_node *n)
}
TIMER_OF_DECLARE(riscv_timer, "riscv", riscv_timer_init_dt);
+
+#ifdef CONFIG_ACPI
+static int __init riscv_timer_acpi_init(struct acpi_table_header *table)
+{
+ return riscv_timer_init_common();
+}
+
+TIMER_ACPI_DECLARE(aclint_mtimer, ACPI_SIG_RHCT, riscv_timer_acpi_init);
+
+#endif
--
2.34.1
Initialize the ACPI core for RISC-V during boot.
ACPI tables and interpreter are initialized based on
the information passed from the firmware and the value of
the kernel parameter 'acpi'.
With ACPI support added for RISC-V, the kernel parameter 'acpi'
is also supported on RISC-V. Hence, update the documentation.
Signed-off-by: Sunil V L <[email protected]>
Acked-by: Rafael J. Wysocki <[email protected]>
Reviewed-by: Andrew Jones <[email protected]>
---
.../admin-guide/kernel-parameters.txt | 8 +-
arch/riscv/kernel/acpi.c | 126 ++++++++++++++++++
arch/riscv/kernel/setup.c | 25 ++--
3 files changed, 147 insertions(+), 12 deletions(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 6221a1d057dd..047679554453 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1,17 +1,17 @@
- acpi= [HW,ACPI,X86,ARM64]
+ acpi= [HW,ACPI,X86,ARM64,RISCV64]
Advanced Configuration and Power Interface
Format: { force | on | off | strict | noirq | rsdt |
copy_dsdt }
force -- enable ACPI if default was off
- on -- enable ACPI but allow fallback to DT [arm64]
+ on -- enable ACPI but allow fallback to DT [arm64,riscv64]
off -- disable ACPI if default was on
noirq -- do not use ACPI for IRQ routing
strict -- Be less tolerant of platforms that are not
strictly ACPI specification compliant.
rsdt -- prefer RSDT over (default) XSDT
copy_dsdt -- copy DSDT to memory
- For ARM64, ONLY "acpi=off", "acpi=on" or "acpi=force"
- are available
+ For ARM64 and RISCV64, ONLY "acpi=off", "acpi=on" or
+ "acpi=force" are available
See also Documentation/power/runtime_pm.rst, pci=noacpi
diff --git a/arch/riscv/kernel/acpi.c b/arch/riscv/kernel/acpi.c
index 8b3d68d8225f..9b6841700e30 100644
--- a/arch/riscv/kernel/acpi.c
+++ b/arch/riscv/kernel/acpi.c
@@ -16,6 +16,7 @@
#include <linux/acpi.h>
#include <linux/io.h>
#include <linux/pci.h>
+#include <linux/efi.h>
int acpi_noirq = 1; /* skip ACPI IRQ initialization */
int acpi_disabled = 1;
@@ -25,6 +26,131 @@ int acpi_pci_disabled = 1; /* skip ACPI PCI scan and IRQ initialization */
EXPORT_SYMBOL(acpi_pci_disabled);
static struct acpi_madt_rintc cpu_madt_rintc[NR_CPUS];
+static bool param_acpi_off __initdata;
+static bool param_acpi_on __initdata;
+static bool param_acpi_force __initdata;
+
+static int __init parse_acpi(char *arg)
+{
+ if (!arg)
+ return -EINVAL;
+
+ /* "acpi=off" disables both ACPI table parsing and interpreter */
+ if (strcmp(arg, "off") == 0)
+ param_acpi_off = true;
+ else if (strcmp(arg, "on") == 0) /* prefer ACPI over DT */
+ param_acpi_on = true;
+ else if (strcmp(arg, "force") == 0) /* force ACPI to be enabled */
+ param_acpi_force = true;
+ else
+ return -EINVAL; /* Core will print when we return error */
+
+ return 0;
+}
+early_param("acpi", parse_acpi);
+
+/*
+ * acpi_fadt_sanity_check() - Check FADT presence and carry out sanity
+ * checks on it
+ *
+ * Return 0 on success, <0 on failure
+ */
+static int __init acpi_fadt_sanity_check(void)
+{
+ struct acpi_table_header *table;
+ struct acpi_table_fadt *fadt;
+ acpi_status status;
+ int ret = 0;
+
+ /*
+ * FADT is required on riscv; retrieve it to check its presence
+ * and carry out revision and ACPI HW reduced compliancy tests
+ */
+ status = acpi_get_table(ACPI_SIG_FADT, 0, &table);
+ if (ACPI_FAILURE(status)) {
+ const char *msg = acpi_format_exception(status);
+
+ pr_err("Failed to get FADT table, %s\n", msg);
+ return -ENODEV;
+ }
+
+ fadt = (struct acpi_table_fadt *)table;
+
+ /*
+ * Revision in table header is the FADT Major revision, and there
+ * is a minor revision of FADT.
+ *
+ * TODO: Currently, we check for 6.5 as the minimum version to check
+ * for HW_REDUCED flag. However, once RISC-V updates are released in
+ * the ACPI spec, we need to update this check for exact minor revision
+ */
+ if (table->revision < 6 || (table->revision == 6 && fadt->minor_revision < 5)) {
+ pr_err(FW_BUG "Unsupported FADT revision %d.%d, should be 6.5+\n",
+ table->revision, fadt->minor_revision);
+ }
+
+ if (!(fadt->flags & ACPI_FADT_HW_REDUCED)) {
+ pr_err("FADT not ACPI hardware reduced compliant\n");
+ ret = -EINVAL;
+ }
+
+ /*
+ * acpi_get_table() creates FADT table mapping that
+ * should be released after parsing and before resuming boot
+ */
+ acpi_put_table(table);
+ return ret;
+}
+
+/*
+ * acpi_boot_table_init() called from setup_arch(), always.
+ * 1. find RSDP and get its address, and then find XSDT
+ * 2. extract all tables and checksums them all
+ * 3. check ACPI FADT HW reduced flag
+ *
+ * We can parse ACPI boot-time tables such as MADT after
+ * this function is called.
+ *
+ * On return ACPI is enabled if either:
+ *
+ * - ACPI tables are initialized and sanity checks passed
+ * - acpi=force was passed in the command line and ACPI was not disabled
+ * explicitly through acpi=off command line parameter
+ *
+ * ACPI is disabled on function return otherwise
+ */
+void __init acpi_boot_table_init(void)
+{
+ /*
+ * Enable ACPI instead of device tree unless
+ * - ACPI has been disabled explicitly (acpi=off), or
+ * - firmware has not populated ACPI ptr in EFI system table
+ * and ACPI has not been [force] enabled (acpi=on|force)
+ */
+ if (param_acpi_off ||
+ (!param_acpi_on && !param_acpi_force &&
+ efi.acpi20 == EFI_INVALID_TABLE_ADDR))
+ return;
+
+ /*
+ * ACPI is disabled at this point. Enable it in order to parse
+ * the ACPI tables and carry out sanity checks
+ */
+ enable_acpi();
+
+ /*
+ * If ACPI tables are initialized and FADT sanity checks passed,
+ * leave ACPI enabled and carry on booting; otherwise disable ACPI
+ * on initialization error.
+ * If acpi=force was passed on the command line it forces ACPI
+ * to be enabled even if its initialization failed.
+ */
+ if (acpi_table_init() || acpi_fadt_sanity_check()) {
+ pr_err("Failed to init ACPI tables\n");
+ if (!param_acpi_force)
+ disable_acpi();
+ }
+}
static int acpi_parse_madt_rintc(union acpi_subtable_headers *header, const unsigned long end)
{
diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
index 2d45a416d283..7b2b065a9f70 100644
--- a/arch/riscv/kernel/setup.c
+++ b/arch/riscv/kernel/setup.c
@@ -8,6 +8,7 @@
* Nick Kossifidis <[email protected]>
*/
+#include <linux/acpi.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/memblock.h>
@@ -276,14 +277,22 @@ void __init setup_arch(char **cmdline_p)
efi_init();
paging_init();
-#if IS_ENABLED(CONFIG_BUILTIN_DTB)
- unflatten_and_copy_device_tree();
-#else
- if (early_init_dt_verify(__va(XIP_FIXUP(dtb_early_pa))))
- unflatten_device_tree();
- else
- pr_err("No DTB found in kernel mappings\n");
-#endif
+
+ /* Parse the ACPI tables for possible boot-time configuration */
+ acpi_boot_table_init();
+ if (acpi_disabled) {
+ if (IS_ENABLED(CONFIG_BUILTIN_DTB)) {
+ unflatten_and_copy_device_tree();
+ } else {
+ if (early_init_dt_verify(__va(XIP_FIXUP(dtb_early_pa))))
+ unflatten_device_tree();
+ else
+ pr_err("No DTB found in kernel mappings\n");
+ }
+ } else {
+ early_init_dt_verify(__va(XIP_FIXUP(dtb_early_pa)));
+ }
+
early_init_fdt_scan_reserved_mem();
misc_mem_init();
--
2.34.1
On ACPI based platforms, timer related information is
available in RHCT. Add ACPI based probe support to the
timer initialization.
Signed-off-by: Sunil V L <[email protected]>
Acked-by: Rafael J. Wysocki <[email protected]>
Reviewed-by: Andrew Jones <[email protected]>
---
arch/riscv/kernel/time.c | 23 +++++++++++++++++------
1 file changed, 17 insertions(+), 6 deletions(-)
diff --git a/arch/riscv/kernel/time.c b/arch/riscv/kernel/time.c
index babaf3b48ba8..2c29543549c3 100644
--- a/arch/riscv/kernel/time.c
+++ b/arch/riscv/kernel/time.c
@@ -4,6 +4,7 @@
* Copyright (C) 2017 SiFive
*/
+#include <linux/acpi.h>
#include <linux/of_clk.h>
#include <linux/clockchips.h>
#include <linux/clocksource.h>
@@ -18,17 +19,27 @@ EXPORT_SYMBOL_GPL(riscv_timebase);
void __init time_init(void)
{
struct device_node *cpu;
+ struct acpi_table_rhct *rhct;
+ acpi_status status;
u32 prop;
- cpu = of_find_node_by_path("/cpus");
- if (!cpu || of_property_read_u32(cpu, "timebase-frequency", &prop))
- panic(KERN_WARNING "RISC-V system with no 'timebase-frequency' in DTS\n");
- of_node_put(cpu);
- riscv_timebase = prop;
+ if (acpi_disabled) {
+ cpu = of_find_node_by_path("/cpus");
+ if (!cpu || of_property_read_u32(cpu, "timebase-frequency", &prop))
+ panic("RISC-V system with no 'timebase-frequency' in DTS\n");
+ of_node_put(cpu);
+ riscv_timebase = prop;
+ of_clk_init(NULL);
+ } else {
+ status = acpi_get_table(ACPI_SIG_RHCT, 0, (struct acpi_table_header **)&rhct);
+ if (ACPI_FAILURE(status))
+ panic("RISC-V ACPI system with no RHCT table\n");
+ riscv_timebase = rhct->time_base_freq;
+ acpi_put_table((struct acpi_table_header *)rhct);
+ }
lpj_fine = riscv_timebase / HZ;
- of_clk_init(NULL);
timer_probe();
tick_setup_hrtimer_broadcast();
--
2.34.1
ACPI defines few RISC-V specific tables which need
parsing code added in drivers/acpi/riscv. Add maintainer
entries for this newly created folder.
Signed-off-by: Sunil V L <[email protected]>
Acked-by: Rafael J. Wysocki <[email protected]>
---
MAINTAINERS | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index b0db911207ba..c299f88cb212 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -406,6 +406,14 @@ L: [email protected] (moderated for non-subscribers)
S: Maintained
F: drivers/acpi/arm64
+ACPI FOR RISC-V (ACPI/riscv)
+M: Sunil V L <[email protected]>
+L: [email protected]
+L: [email protected]
+S: Maintained
+F: arch/riscv/kernel/acpi.c
+F: drivers/acpi/riscv
+
ACPI SERIAL MULTI INSTANTIATE DRIVER
M: Hans de Goede <[email protected]>
L: [email protected]
--
2.34.1
Add support to build ACPI subsystem in defconfig.
Signed-off-by: Sunil V L <[email protected]>
Acked-by: Rafael J. Wysocki <[email protected]>
---
arch/riscv/configs/defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig
index d98d6e90b2b8..8822b49ddb59 100644
--- a/arch/riscv/configs/defconfig
+++ b/arch/riscv/configs/defconfig
@@ -238,3 +238,4 @@ CONFIG_RCU_EQS_DEBUG=y
# CONFIG_FTRACE is not set
# CONFIG_RUNTIME_TESTING_MENU is not set
CONFIG_MEMTEST=y
+CONFIG_ACPI=y
--
2.34.1
On Fri, Mar 03, 2023 at 07:06:31PM +0530, Sunil V L wrote:
> When MADT is parsed, print RINTC information as below:
>
> ACPI: RISC-V INTC (acpi_uid[0x0000] hart_id[0x0] enabled)
> ACPI: RISC-V INTC (acpi_uid[0x0001] hart_id[0x1] enabled)
> ...
> ACPI: RISC-V INTC (acpi_uid[0x000f] hart_id[0xf] enabled)
>
> This debug information will be very helpful during bring up.
>
> Signed-off-by: Sunil V L <[email protected]>
> Acked-by: Rafael J. Wysocki <[email protected]>
> ---
> drivers/acpi/tables.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
> index 7b4680da57d7..8ab0a82b4da4 100644
> --- a/drivers/acpi/tables.c
> +++ b/drivers/acpi/tables.c
> @@ -220,6 +220,16 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
> }
> break;
>
> + case ACPI_MADT_TYPE_RINTC:
> + {
> + struct acpi_madt_rintc *p = (struct acpi_madt_rintc *)header;
> +
> + pr_debug("RISC-V INTC (acpi_uid[0x%04x] hart_id[0x%llx] %s)\n",
> + p->uid, p->hart_id,
> + (p->flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
> + }
> + break;
> +
> default:
> pr_warn("Found unsupported MADT entry (type = 0x%x)\n",
> header->type);
> --
> 2.34.1
>
Reviewed-by: Andrew Jones <[email protected]>
On Fri, Mar 03, 2023 at 07:06:33PM +0530, Sunil V L wrote:
> Enable ACPI core for RISC-V after adding architecture-specific
> interfaces and header files required to build the ACPI core.
>
> 1) Couple of header files are required unconditionally by the ACPI
> core. Add empty acenv.h and cpu.h header files.
>
> 2) If CONFIG_PCI is enabled, a few PCI related interfaces need to
> be provided by the architecture. Define dummy interfaces for now
> so that build succeeds. Actual implementation will be added when
> PCI support is added for ACPI along with external interrupt
> controller support.
>
> 3) A few globals and memory mapping related functions specific
> to the architecture need to be provided.
>
> Signed-off-by: Sunil V L <[email protected]>
> Acked-by: Rafael J. Wysocki <[email protected]>
> Reviewed-by: Andrew Jones <[email protected]>
> ---
> arch/riscv/Kconfig | 5 +++
> arch/riscv/include/asm/acenv.h | 11 +++++
> arch/riscv/include/asm/acpi.h | 61 ++++++++++++++++++++++++++
> arch/riscv/include/asm/cpu.h | 8 ++++
> arch/riscv/kernel/Makefile | 2 +
> arch/riscv/kernel/acpi.c | 80 ++++++++++++++++++++++++++++++++++
> 6 files changed, 167 insertions(+)
> create mode 100644 arch/riscv/include/asm/acenv.h
> create mode 100644 arch/riscv/include/asm/acpi.h
> create mode 100644 arch/riscv/include/asm/cpu.h
> create mode 100644 arch/riscv/kernel/acpi.c
>
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index 71754eb32ee6..f3108c7e19d8 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -12,6 +12,8 @@ config 32BIT
>
> config RISCV
> def_bool y
> + select ACPI_GENERIC_GSI if ACPI
> + select ACPI_REDUCED_HARDWARE_ONLY if ACPI
> select ARCH_ENABLE_HUGEPAGE_MIGRATION if HUGETLB_PAGE && MIGRATION
> select ARCH_ENABLE_SPLIT_PMD_PTLOCK if PGTABLE_LEVELS > 2
> select ARCH_ENABLE_THP_MIGRATION if TRANSPARENT_HUGEPAGE
> @@ -617,6 +619,7 @@ config EFI
> depends on OF && !XIP_KERNEL
> depends on MMU
> default y
> + select ARCH_SUPPORTS_ACPI if 64BIT
> select EFI_GENERIC_STUB
> select EFI_PARAMS_FROM_FDT
> select EFI_RUNTIME_WRAPPERS
> @@ -720,3 +723,5 @@ source "drivers/cpufreq/Kconfig"
> endmenu # "CPU Power Management"
>
> source "arch/riscv/kvm/Kconfig"
> +
> +source "drivers/acpi/Kconfig"
The above Kconfig hunks don't apply on the IPI improvement base. The
second hunk also looks weird with the select under the default.
Thanks,
drew
On Fri, Mar 03, 2023 at 07:06:37PM +0530, Sunil V L wrote:
> Enable SMP boot on ACPI based platforms by using the RINTC
> structures in the MADT table.
>
> Signed-off-by: Sunil V L <[email protected]>
> Acked-by: Rafael J. Wysocki <[email protected]>
> Reviewed-by: Conor Dooley <[email protected]>
> ---
> arch/riscv/kernel/smpboot.c | 72 ++++++++++++++++++++++++++++++++++++-
> 1 file changed, 71 insertions(+), 1 deletion(-)
>
> diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c
> index 26214ddefaa4..27047322d3bb 100644
> --- a/arch/riscv/kernel/smpboot.c
> +++ b/arch/riscv/kernel/smpboot.c
> @@ -8,6 +8,7 @@
> * Copyright (C) 2017 SiFive
> */
>
> +#include <linux/acpi.h>
> #include <linux/arch_topology.h>
> #include <linux/module.h>
> #include <linux/init.h>
> @@ -70,6 +71,72 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
> }
> }
>
> +#ifdef CONFIG_ACPI
> +static unsigned int cpu_count = 1;
> +
> +static int __init acpi_parse_rintc(union acpi_subtable_headers *header, const unsigned long end)
> +{
> + unsigned long hart;
> + static bool found_boot_cpu;
> + struct acpi_madt_rintc *processor = (struct acpi_madt_rintc *)header;
> +
> + /*
> + * Each RINTC structure in MADT will have a flag. If ACPI_MADT_ENABLED
> + * bit in the flag is not enabled, it means OS should not try to enable
> + * the cpu to which RINTC belongs.
> + */
> + if (!(processor->flags & ACPI_MADT_ENABLED))
> + return 0;
> +
> + if (BAD_MADT_ENTRY(processor, end))
> + return -EINVAL;
> +
> + acpi_table_print_madt_entry(&header->common);
> +
> + hart = processor->hart_id;
> + if (hart == INVALID_HARTID) {
> + pr_warn("Invalid hartid\n");
> + return 0;
> + }
> +
> + if (hart == cpuid_to_hartid_map(0)) {
> + BUG_ON(found_boot_cpu);
> + found_boot_cpu = true;
> + early_map_cpu_to_node(0, NUMA_NO_NODE);
We should have kept
static inline int acpi_numa_get_nid(unsigned int cpu) { return NUMA_NO_NODE; }
and only dropped the
#ifdef CONFIG_ACPI_NUMA
int acpi_numa_get_nid(unsigned int cpu);
#else
...
#endif
> + return 0;
> + }
> +
> + if (cpu_count >= NR_CPUS) {
> + pr_warn("NR_CPUS is too small for the number of ACPI tables.\n");
> + return 0;
> + }
> +
> + cpuid_to_hartid_map(cpu_count) = hart;
> + early_map_cpu_to_node(cpu_count, NUMA_NO_NODE);
> + cpu_count++;
> +
> + return 0;
> +}
> +
> +static void __init acpi_parse_and_init_cpus(void)
> +{
> + int cpuid;
> +
> + cpu_set_ops(0);
> +
> + acpi_table_parse_madt(ACPI_MADT_TYPE_RINTC, acpi_parse_rintc, 0);
> +
> + for (cpuid = 1; cpuid < nr_cpu_ids; cpuid++) {
> + if (cpuid_to_hartid_map(cpuid) != INVALID_HARTID) {
> + cpu_set_ops(cpuid);
> + set_cpu_possible(cpuid, true);
> + }
> + }
> +}
> +#else
> +#define acpi_parse_and_init_cpus(...) do { } while (0)
> +#endif
> +
> static void __init of_parse_and_init_cpus(void)
> {
> struct device_node *dn;
> @@ -118,7 +185,10 @@ static void __init of_parse_and_init_cpus(void)
>
> void __init setup_smp(void)
> {
> - of_parse_and_init_cpus();
> + if (acpi_disabled)
> + of_parse_and_init_cpus();
> + else
> + acpi_parse_and_init_cpus();
> }
>
> static int start_secondary_cpu(int cpu, struct task_struct *tidle)
> --
> 2.34.1
>
Thanks,
drew
On Fri, Mar 03, 2023 at 07:06:38PM +0530, Sunil V L wrote:
> RINTC structures in the MADT provide mapping between the hartid
> and the CPU. This is required many times even at run time like
> cpuinfo. So, instead of parsing the ACPI table every time, cache
> the RINTC structures and provide a function to get the correct
> RINTC structure for a given cpu.
>
> Signed-off-by: Sunil V L <[email protected]>
> Acked-by: Rafael J. Wysocki <[email protected]>
> ---
> arch/riscv/include/asm/acpi.h | 9 ++++++
> arch/riscv/kernel/acpi.c | 56 +++++++++++++++++++++++++++++++++++
> 2 files changed, 65 insertions(+)
>
> diff --git a/arch/riscv/include/asm/acpi.h b/arch/riscv/include/asm/acpi.h
> index 111a8ed10af1..8be16c1ef7da 100644
> --- a/arch/riscv/include/asm/acpi.h
> +++ b/arch/riscv/include/asm/acpi.h
> @@ -61,6 +61,10 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
>
> int acpi_get_riscv_isa(struct acpi_table_header *table,
> unsigned int cpu, const char **isa);
> +
> +struct acpi_madt_rintc *acpi_cpu_get_madt_rintc(int cpu);
> +
> +u32 get_acpi_id_for_cpu(int cpu);
> #else
> static inline int acpi_get_riscv_isa(struct acpi_table_header *table,
> unsigned int cpu, const char **isa)
> @@ -68,6 +72,11 @@ static inline int acpi_get_riscv_isa(struct acpi_table_header *table,
> return -EINVAL;
> }
>
> +static inline u32 get_acpi_id_for_cpu(int cpu)
> +{
> + return -1;
> +}
Why do we need this stub? I wouldn't expect non-ACPI code to need an ACPI
ID.
> +
> #endif /* CONFIG_ACPI */
>
> #endif /*_ASM_ACPI_H*/
> diff --git a/arch/riscv/kernel/acpi.c b/arch/riscv/kernel/acpi.c
> index 81d448c41714..8b3d68d8225f 100644
> --- a/arch/riscv/kernel/acpi.c
> +++ b/arch/riscv/kernel/acpi.c
> @@ -24,6 +24,62 @@ EXPORT_SYMBOL(acpi_disabled);
> int acpi_pci_disabled = 1; /* skip ACPI PCI scan and IRQ initialization */
> EXPORT_SYMBOL(acpi_pci_disabled);
>
> +static struct acpi_madt_rintc cpu_madt_rintc[NR_CPUS];
> +
> +static int acpi_parse_madt_rintc(union acpi_subtable_headers *header, const unsigned long end)
> +{
> + struct acpi_madt_rintc *rintc = (struct acpi_madt_rintc *)header;
> + int cpuid;
> +
> + if (!(rintc->flags & ACPI_MADT_ENABLED))
> + return 0;
Why not cache the data even when its disabled? We also cache the flags so
we can always check later too.
> +
> + cpuid = riscv_hartid_to_cpuid(rintc->hart_id);
> + if (cpuid >= 0 && cpuid < NR_CPUS)
What does it mean for the above check to fail? Bad ACPI tables?
> + cpu_madt_rintc[cpuid] = *rintc;
> +
> + return 0;
> +}
> +
> +static int acpi_init_rintc_array(void)
> +{
> + if (acpi_table_parse_madt(ACPI_MADT_TYPE_RINTC, acpi_parse_madt_rintc, 0) > 0)
> + return 0;
> +
> + return -ENODEV;
> +}
> +
> +/*
> + * Instead of parsing (and freeing) the ACPI table, cache
> + * the RINTC structures since they are frequently used
> + * like in cpuinfo.
> + */
> +struct acpi_madt_rintc *acpi_cpu_get_madt_rintc(int cpu)
> +{
> + static bool rintc_init_done;
> +
> + if (!rintc_init_done) {
> + if (acpi_init_rintc_array()) {
> + pr_err("No valid RINTC entries exist\n");
> + return NULL;
> + }
> +
> + rintc_init_done = true;
> + }
> +
> + return &cpu_madt_rintc[cpu];
> +}
> +
> +u32 get_acpi_id_for_cpu(int cpu)
> +{
> + struct acpi_madt_rintc *rintc = acpi_cpu_get_madt_rintc(cpu);
> +
> + if (!rintc)
> + return -1;
Is -1 defined as an invalid ACPI ID? I'm wondering if we shouldn't just
BUG in acpi_init_rintc_array() if we fail to initialize and then we can
unconditionally return rintc->uid here.
> +
> + return rintc->uid;
> +}
> +
> /*
> * __acpi_map_table() will be called before paging_init(), so early_ioremap()
> * or early_memremap() should be called here to for ACPI table mapping.
> --
> 2.34.1
>
Thanks,
drew
On Fri, Mar 03, 2023 at 07:06:39PM +0530, Sunil V L wrote:
> On ACPI based systems, the information about the hart
> like ISA is provided by the RISC-V Hart Capabilities Table (RHCT).
> Enable filling up hwcap structure based on the information in RHCT.
>
> Signed-off-by: Sunil V L <[email protected]>
> Acked-by: Rafael J. Wysocki <[email protected]>
> ---
> arch/riscv/kernel/cpufeature.c | 41 ++++++++++++++++++++++++++--------
> 1 file changed, 32 insertions(+), 9 deletions(-)
>
> diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
> index 59d58ee0f68d..478dbf129922 100644
> --- a/arch/riscv/kernel/cpufeature.c
> +++ b/arch/riscv/kernel/cpufeature.c
> @@ -6,6 +6,7 @@
> * Copyright (C) 2017 SiFive
> */
>
> +#include <linux/acpi.h>
> #include <linux/bitmap.h>
> #include <linux/ctype.h>
> #include <linux/libfdt.h>
> @@ -13,6 +14,8 @@
> #include <linux/memory.h>
> #include <linux/module.h>
> #include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <asm/acpi.h>
> #include <asm/alternative.h>
> #include <asm/cacheflush.h>
> #include <asm/errata_list.h>
> @@ -91,7 +94,9 @@ void __init riscv_fill_hwcap(void)
> char print_str[NUM_ALPHA_EXTS + 1];
> int i, j, rc;
> unsigned long isa2hwcap[26] = {0};
> - unsigned long hartid;
> + struct acpi_table_header *rhct;
> + acpi_status status;
> + unsigned int cpu;
>
> isa2hwcap['i' - 'a'] = COMPAT_HWCAP_ISA_I;
> isa2hwcap['m' - 'a'] = COMPAT_HWCAP_ISA_M;
> @@ -104,18 +109,33 @@ void __init riscv_fill_hwcap(void)
>
> bitmap_zero(riscv_isa, RISCV_ISA_EXT_MAX);
>
> - for_each_of_cpu_node(node) {
> + if (!acpi_disabled) {
> + status = acpi_get_table(ACPI_SIG_RHCT, 0, &rhct);
> + if (ACPI_FAILURE(status))
> + return;
> + }
> +
> + for_each_possible_cpu(cpu) {
> unsigned long this_hwcap = 0;
> DECLARE_BITMAP(this_isa, RISCV_ISA_EXT_MAX);
> const char *temp;
>
> - rc = riscv_of_processor_hartid(node, &hartid);
> - if (rc < 0)
> - continue;
The above is an unrelated cleanup and should be in a separate patch.
> -
> - if (of_property_read_string(node, "riscv,isa", &isa)) {
> - pr_warn("Unable to find \"riscv,isa\" devicetree entry\n");
> - continue;
> + if (acpi_disabled) {
> + node = of_cpu_device_node_get(cpu);
> + if (node) {
> + rc = of_property_read_string(node, "riscv,isa", &isa);
> + of_node_put(node);
> + if (rc) {
> + pr_warn("Unable to find \"riscv,isa\" devicetree entry\n");
> + continue;
> + }
> + }
> + } else {
> + rc = acpi_get_riscv_isa(rhct, get_acpi_id_for_cpu(cpu), &isa);
> + if (rc < 0) {
> + pr_warn("Unable to get ISA for the hart - %d\n", cpu);
> + continue;
> + }
> }
>
> temp = isa;
> @@ -248,6 +268,9 @@ void __init riscv_fill_hwcap(void)
> bitmap_and(riscv_isa, riscv_isa, this_isa, RISCV_ISA_EXT_MAX);
> }
>
> + if (!acpi_disabled && rhct)
> + acpi_put_table((struct acpi_table_header *)rhct);
> +
> /* We don't support systems with F but without D, so mask those out
> * here. */
> if ((elf_hwcap & COMPAT_HWCAP_ISA_F) && !(elf_hwcap & COMPAT_HWCAP_ISA_D)) {
> --
> 2.34.1
>
Otherwise,
Reviewed-by: Andrew Jones <[email protected]>
Thanks,
drew
On Fri, Mar 03, 2023 at 07:06:40PM +0530, Sunil V L wrote:
> On ACPI based platforms, few details like ISA need to be read
> from the ACPI table. Enable cpuinfo on ACPI based systems.
>
> Signed-off-by: Sunil V L <[email protected]>
> Acked-by: Rafael J. Wysocki <[email protected]>
> ---
> arch/riscv/kernel/cpu.c | 27 +++++++++++++++++++--------
> 1 file changed, 19 insertions(+), 8 deletions(-)
>
> diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
> index 8400f0cc9704..80101bf77dab 100644
> --- a/arch/riscv/kernel/cpu.c
> +++ b/arch/riscv/kernel/cpu.c
> @@ -3,10 +3,12 @@
> * Copyright (C) 2012 Regents of the University of California
> */
>
> +#include <linux/acpi.h>
> #include <linux/cpu.h>
> #include <linux/init.h>
> #include <linux/seq_file.h>
> #include <linux/of.h>
> +#include <asm/acpi.h>
> #include <asm/csr.h>
> #include <asm/hwcap.h>
> #include <asm/sbi.h>
> @@ -283,23 +285,32 @@ static void c_stop(struct seq_file *m, void *v)
> static int c_show(struct seq_file *m, void *v)
> {
> unsigned long cpu_id = (unsigned long)v - 1;
> - struct device_node *node = of_get_cpu_node(cpu_id, NULL);
> struct riscv_cpuinfo *ci = per_cpu_ptr(&riscv_cpuinfo, cpu_id);
> + struct device_node *node;
> const char *compat, *isa;
>
> seq_printf(m, "processor\t: %lu\n", cpu_id);
> seq_printf(m, "hart\t\t: %lu\n", cpuid_to_hartid_map(cpu_id));
> - if (!of_property_read_string(node, "riscv,isa", &isa))
> - print_isa(m, isa);
> - print_mmu(m);
> - if (!of_property_read_string(node, "compatible", &compat)
> - && strcmp(compat, "riscv"))
> - seq_printf(m, "uarch\t\t: %s\n", compat);
> +
> + if (acpi_disabled) {
> + node = of_get_cpu_node(cpu_id, NULL);
> + if (!of_property_read_string(node, "riscv,isa", &isa))
> + print_isa(m, isa);
> + print_mmu(m);
> + if (!of_property_read_string(node, "compatible", &compat) &&
> + strcmp(compat, "riscv"))
> + seq_printf(m, "uarch\t\t: %s\n", compat);
> + of_node_put(node);
> + } else {
> + if (!acpi_get_riscv_isa(NULL, get_acpi_id_for_cpu(cpu_id), &isa))
> + print_isa(m, isa);
> + print_mmu(m);
> + }
> +
> seq_printf(m, "mvendorid\t: 0x%lx\n", ci->mvendorid);
> seq_printf(m, "marchid\t\t: 0x%lx\n", ci->marchid);
> seq_printf(m, "mimpid\t\t: 0x%lx\n", ci->mimpid);
> seq_puts(m, "\n");
> - of_node_put(node);
>
> return 0;
> }
> --
> 2.34.1
>
Reviewed-by: Andrew Jones <[email protected]>
On Fri, Mar 03, 2023 at 07:06:46PM +0530, Sunil V L wrote:
> Add support to build ACPI subsystem in defconfig.
>
> Signed-off-by: Sunil V L <[email protected]>
> Acked-by: Rafael J. Wysocki <[email protected]>
> ---
> arch/riscv/configs/defconfig | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig
> index d98d6e90b2b8..8822b49ddb59 100644
> --- a/arch/riscv/configs/defconfig
> +++ b/arch/riscv/configs/defconfig
> @@ -238,3 +238,4 @@ CONFIG_RCU_EQS_DEBUG=y
> # CONFIG_FTRACE is not set
> # CONFIG_RUNTIME_TESTING_MENU is not set
> CONFIG_MEMTEST=y
> +CONFIG_ACPI=y
> --
> 2.34.1
>
Reviewed-by: Andrew Jones <[email protected]>
On Fri, Mar 03, 2023 at 05:05:56PM +0100, Andrew Jones wrote:
> On Fri, Mar 03, 2023 at 07:06:38PM +0530, Sunil V L wrote:
> > RINTC structures in the MADT provide mapping between the hartid
> > and the CPU. This is required many times even at run time like
> > cpuinfo. So, instead of parsing the ACPI table every time, cache
> > the RINTC structures and provide a function to get the correct
> > RINTC structure for a given cpu.
> >
> > Signed-off-by: Sunil V L <[email protected]>
> > Acked-by: Rafael J. Wysocki <[email protected]>
> > ---
> > arch/riscv/include/asm/acpi.h | 9 ++++++
> > arch/riscv/kernel/acpi.c | 56 +++++++++++++++++++++++++++++++++++
> > 2 files changed, 65 insertions(+)
> > diff --git a/arch/riscv/include/asm/acpi.h b/arch/riscv/include/asm/acpi.h
> > index 111a8ed10af1..8be16c1ef7da 100644
> > --- a/arch/riscv/include/asm/acpi.h
> > +++ b/arch/riscv/include/asm/acpi.h
> > @@ -61,6 +61,10 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
> >
> > int acpi_get_riscv_isa(struct acpi_table_header *table,
> > unsigned int cpu, const char **isa);
> > +
> > +struct acpi_madt_rintc *acpi_cpu_get_madt_rintc(int cpu);
> > +
> > +u32 get_acpi_id_for_cpu(int cpu);
> > #else
> > static inline int acpi_get_riscv_isa(struct acpi_table_header *table,
> > unsigned int cpu, const char **isa)
> > @@ -68,6 +72,11 @@ static inline int acpi_get_riscv_isa(struct acpi_table_header *table,
> > return -EINVAL;
> > }
> >
> > +static inline u32 get_acpi_id_for_cpu(int cpu)
> > +{
> > + return -1;
> > +}
>
> Why do we need this stub? I wouldn't expect non-ACPI code to need an ACPI
> ID.
I think I asked for this (or assumed it existed) in v1, when I requested
the removal of #ifdef CONFIG_ACPI stuff in riscv_fill_hwcap().
Personally, I'd rather have this stub than the ifdeffery :)
Cheers,
Conor.
On Fri, Mar 03, 2023 at 04:58:53PM +0000, Conor Dooley wrote:
> On Fri, Mar 03, 2023 at 05:05:56PM +0100, Andrew Jones wrote:
> > On Fri, Mar 03, 2023 at 07:06:38PM +0530, Sunil V L wrote:
> > > RINTC structures in the MADT provide mapping between the hartid
> > > and the CPU. This is required many times even at run time like
> > > cpuinfo. So, instead of parsing the ACPI table every time, cache
> > > the RINTC structures and provide a function to get the correct
> > > RINTC structure for a given cpu.
> > >
> > > Signed-off-by: Sunil V L <[email protected]>
> > > Acked-by: Rafael J. Wysocki <[email protected]>
> > > ---
> > > arch/riscv/include/asm/acpi.h | 9 ++++++
> > > arch/riscv/kernel/acpi.c | 56 +++++++++++++++++++++++++++++++++++
> > > 2 files changed, 65 insertions(+)
>
> > > diff --git a/arch/riscv/include/asm/acpi.h b/arch/riscv/include/asm/acpi.h
> > > index 111a8ed10af1..8be16c1ef7da 100644
> > > --- a/arch/riscv/include/asm/acpi.h
> > > +++ b/arch/riscv/include/asm/acpi.h
> > > @@ -61,6 +61,10 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
> > >
> > > int acpi_get_riscv_isa(struct acpi_table_header *table,
> > > unsigned int cpu, const char **isa);
> > > +
> > > +struct acpi_madt_rintc *acpi_cpu_get_madt_rintc(int cpu);
> > > +
> > > +u32 get_acpi_id_for_cpu(int cpu);
> > > #else
> > > static inline int acpi_get_riscv_isa(struct acpi_table_header *table,
> > > unsigned int cpu, const char **isa)
> > > @@ -68,6 +72,11 @@ static inline int acpi_get_riscv_isa(struct acpi_table_header *table,
> > > return -EINVAL;
> > > }
> > >
> > > +static inline u32 get_acpi_id_for_cpu(int cpu)
> > > +{
> > > + return -1;
> > > +}
> >
> > Why do we need this stub? I wouldn't expect non-ACPI code to need an ACPI
> > ID.
>
> I think I asked for this (or assumed it existed) in v1, when I requested
> the removal of #ifdef CONFIG_ACPI stuff in riscv_fill_hwcap().
> Personally, I'd rather have this stub than the ifdeffery :)
>
Yeah, avoiding #ifdefs with stubs is good if we need to call the function
from non-ACPI code. I'm wondering why we'd need to, though. In all the
cases introduced with this series, we could pass a 'cpu' to
acpi_get_riscv_isa() and then have acpi_get_riscv_isa() call
get_acpi_id_for_cpu() itself, for example.
We also need to be sure -1 truly means "no ACPI ID" in order to stub this.
Thanks,
drew
On Fri, Mar 03, 2023 at 06:21:13PM +0100, Andrew Jones wrote:
> On Fri, Mar 03, 2023 at 04:58:53PM +0000, Conor Dooley wrote:
> > On Fri, Mar 03, 2023 at 05:05:56PM +0100, Andrew Jones wrote:
> > > On Fri, Mar 03, 2023 at 07:06:38PM +0530, Sunil V L wrote:
> > > > RINTC structures in the MADT provide mapping between the hartid
> > > > and the CPU. This is required many times even at run time like
> > > > cpuinfo. So, instead of parsing the ACPI table every time, cache
> > > > the RINTC structures and provide a function to get the correct
> > > > RINTC structure for a given cpu.
> > > >
> > > > Signed-off-by: Sunil V L <[email protected]>
> > > > Acked-by: Rafael J. Wysocki <[email protected]>
> > > > ---
> > > > arch/riscv/include/asm/acpi.h | 9 ++++++
> > > > arch/riscv/kernel/acpi.c | 56 +++++++++++++++++++++++++++++++++++
> > > > 2 files changed, 65 insertions(+)
> >
> > > > diff --git a/arch/riscv/include/asm/acpi.h b/arch/riscv/include/asm/acpi.h
> > > > index 111a8ed10af1..8be16c1ef7da 100644
> > > > --- a/arch/riscv/include/asm/acpi.h
> > > > +++ b/arch/riscv/include/asm/acpi.h
> > > > @@ -61,6 +61,10 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
> > > >
> > > > int acpi_get_riscv_isa(struct acpi_table_header *table,
> > > > unsigned int cpu, const char **isa);
> > > > +
> > > > +struct acpi_madt_rintc *acpi_cpu_get_madt_rintc(int cpu);
> > > > +
> > > > +u32 get_acpi_id_for_cpu(int cpu);
> > > > #else
> > > > static inline int acpi_get_riscv_isa(struct acpi_table_header *table,
> > > > unsigned int cpu, const char **isa)
> > > > @@ -68,6 +72,11 @@ static inline int acpi_get_riscv_isa(struct acpi_table_header *table,
> > > > return -EINVAL;
> > > > }
> > > >
> > > > +static inline u32 get_acpi_id_for_cpu(int cpu)
> > > > +{
> > > > + return -1;
> > > > +}
> > >
> > > Why do we need this stub? I wouldn't expect non-ACPI code to need an ACPI
> > > ID.
> >
> > I think I asked for this (or assumed it existed) in v1, when I requested
> > the removal of #ifdef CONFIG_ACPI stuff in riscv_fill_hwcap().
> > Personally, I'd rather have this stub than the ifdeffery :)
> >
>
> Yeah, avoiding #ifdefs with stubs is good if we need to call the function
> from non-ACPI code. I'm wondering why we'd need to, though. In all the
> cases introduced with this series, we could pass a 'cpu' to
> acpi_get_riscv_isa() and then have acpi_get_riscv_isa() call
> get_acpi_id_for_cpu() itself, for example.
>
Yes, that's a good idea to avoid the stub. Will update. Thanks!
> We also need to be sure -1 truly means "no ACPI ID" in order to stub this.
>
Yes, with your BUG suggestion I can remove this.
Thanks,
Sunil
On Fri, Mar 03, 2023 at 04:49:20PM +0100, Andrew Jones wrote:
> On Fri, Mar 03, 2023 at 07:06:37PM +0530, Sunil V L wrote:
> > Enable SMP boot on ACPI based platforms by using the RINTC
> > structures in the MADT table.
> >
> > Signed-off-by: Sunil V L <[email protected]>
> > Acked-by: Rafael J. Wysocki <[email protected]>
> > Reviewed-by: Conor Dooley <[email protected]>
> > ---
> > arch/riscv/kernel/smpboot.c | 72 ++++++++++++++++++++++++++++++++++++-
> > 1 file changed, 71 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c
> > index 26214ddefaa4..27047322d3bb 100644
> > --- a/arch/riscv/kernel/smpboot.c
> > +++ b/arch/riscv/kernel/smpboot.c
> > @@ -8,6 +8,7 @@
> > * Copyright (C) 2017 SiFive
> > */
> >
> > +#include <linux/acpi.h>
> > #include <linux/arch_topology.h>
> > #include <linux/module.h>
> > #include <linux/init.h>
> > @@ -70,6 +71,72 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
> > }
> > }
> >
> > +#ifdef CONFIG_ACPI
> > +static unsigned int cpu_count = 1;
> > +
> > +static int __init acpi_parse_rintc(union acpi_subtable_headers *header, const unsigned long end)
> > +{
> > + unsigned long hart;
> > + static bool found_boot_cpu;
> > + struct acpi_madt_rintc *processor = (struct acpi_madt_rintc *)header;
> > +
> > + /*
> > + * Each RINTC structure in MADT will have a flag. If ACPI_MADT_ENABLED
> > + * bit in the flag is not enabled, it means OS should not try to enable
> > + * the cpu to which RINTC belongs.
> > + */
> > + if (!(processor->flags & ACPI_MADT_ENABLED))
> > + return 0;
> > +
> > + if (BAD_MADT_ENTRY(processor, end))
> > + return -EINVAL;
> > +
> > + acpi_table_print_madt_entry(&header->common);
> > +
> > + hart = processor->hart_id;
> > + if (hart == INVALID_HARTID) {
> > + pr_warn("Invalid hartid\n");
> > + return 0;
> > + }
> > +
> > + if (hart == cpuid_to_hartid_map(0)) {
> > + BUG_ON(found_boot_cpu);
> > + found_boot_cpu = true;
> > + early_map_cpu_to_node(0, NUMA_NO_NODE);
>
> We should have kept
>
> static inline int acpi_numa_get_nid(unsigned int cpu) { return NUMA_NO_NODE; }
>
> and only dropped the
>
> #ifdef CONFIG_ACPI_NUMA
> int acpi_numa_get_nid(unsigned int cpu);
> #else
> ...
> #endif
>
Okay, I thought we better add it when we enable NUMA with ACPI.
> > + return 0;
> > + }
> > +
> > + if (cpu_count >= NR_CPUS) {
> > + pr_warn("NR_CPUS is too small for the number of ACPI tables.\n");
> > + return 0;
> > + }
> > +
> > + cpuid_to_hartid_map(cpu_count) = hart;
> > + early_map_cpu_to_node(cpu_count, NUMA_NO_NODE);
> > + cpu_count++;
> > +
> > + return 0;
> > +}
> > +
> > +static void __init acpi_parse_and_init_cpus(void)
> > +{
> > + int cpuid;
> > +
> > + cpu_set_ops(0);
> > +
> > + acpi_table_parse_madt(ACPI_MADT_TYPE_RINTC, acpi_parse_rintc, 0);
> > +
> > + for (cpuid = 1; cpuid < nr_cpu_ids; cpuid++) {
> > + if (cpuid_to_hartid_map(cpuid) != INVALID_HARTID) {
> > + cpu_set_ops(cpuid);
> > + set_cpu_possible(cpuid, true);
> > + }
> > + }
> > +}
> > +#else
> > +#define acpi_parse_and_init_cpus(...) do { } while (0)
> > +#endif
> > +
> > static void __init of_parse_and_init_cpus(void)
> > {
> > struct device_node *dn;
> > @@ -118,7 +185,10 @@ static void __init of_parse_and_init_cpus(void)
> >
> > void __init setup_smp(void)
> > {
> > - of_parse_and_init_cpus();
> > + if (acpi_disabled)
> > + of_parse_and_init_cpus();
> > + else
> > + acpi_parse_and_init_cpus();
> > }
> >
> > static int start_secondary_cpu(int cpu, struct task_struct *tidle)
> > --
> > 2.34.1
> >
>
> Thanks,
> drew
On Fri, Mar 03, 2023 at 05:16:47PM +0100, Andrew Jones wrote:
> On Fri, Mar 03, 2023 at 07:06:39PM +0530, Sunil V L wrote:
> > On ACPI based systems, the information about the hart
> > like ISA is provided by the RISC-V Hart Capabilities Table (RHCT).
> > Enable filling up hwcap structure based on the information in RHCT.
> >
> > Signed-off-by: Sunil V L <[email protected]>
> > Acked-by: Rafael J. Wysocki <[email protected]>
> > ---
> > arch/riscv/kernel/cpufeature.c | 41 ++++++++++++++++++++++++++--------
> > 1 file changed, 32 insertions(+), 9 deletions(-)
> >
> > diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
> > index 59d58ee0f68d..478dbf129922 100644
> > --- a/arch/riscv/kernel/cpufeature.c
> > +++ b/arch/riscv/kernel/cpufeature.c
> > @@ -6,6 +6,7 @@
> > * Copyright (C) 2017 SiFive
> > */
> >
> > +#include <linux/acpi.h>
> > #include <linux/bitmap.h>
> > #include <linux/ctype.h>
> > #include <linux/libfdt.h>
> > @@ -13,6 +14,8 @@
> > #include <linux/memory.h>
> > #include <linux/module.h>
> > #include <linux/of.h>
> > +#include <linux/of_device.h>
> > +#include <asm/acpi.h>
> > #include <asm/alternative.h>
> > #include <asm/cacheflush.h>
> > #include <asm/errata_list.h>
> > @@ -91,7 +94,9 @@ void __init riscv_fill_hwcap(void)
> > char print_str[NUM_ALPHA_EXTS + 1];
> > int i, j, rc;
> > unsigned long isa2hwcap[26] = {0};
> > - unsigned long hartid;
> > + struct acpi_table_header *rhct;
> > + acpi_status status;
> > + unsigned int cpu;
> >
> > isa2hwcap['i' - 'a'] = COMPAT_HWCAP_ISA_I;
> > isa2hwcap['m' - 'a'] = COMPAT_HWCAP_ISA_M;
> > @@ -104,18 +109,33 @@ void __init riscv_fill_hwcap(void)
> >
> > bitmap_zero(riscv_isa, RISCV_ISA_EXT_MAX);
> >
> > - for_each_of_cpu_node(node) {
> > + if (!acpi_disabled) {
> > + status = acpi_get_table(ACPI_SIG_RHCT, 0, &rhct);
> > + if (ACPI_FAILURE(status))
> > + return;
> > + }
> > +
> > + for_each_possible_cpu(cpu) {
> > unsigned long this_hwcap = 0;
> > DECLARE_BITMAP(this_isa, RISCV_ISA_EXT_MAX);
> > const char *temp;
> >
> > - rc = riscv_of_processor_hartid(node, &hartid);
> > - if (rc < 0)
> > - continue;
>
> The above is an unrelated cleanup and should be in a separate patch.
>
Okay, let me split this.
Thanks,
Sunil
On Fri, Mar 03, 2023 at 05:05:56PM +0100, Andrew Jones wrote:
> On Fri, Mar 03, 2023 at 07:06:38PM +0530, Sunil V L wrote:
> > RINTC structures in the MADT provide mapping between the hartid
> > and the CPU. This is required many times even at run time like
> > cpuinfo. So, instead of parsing the ACPI table every time, cache
> > the RINTC structures and provide a function to get the correct
> > RINTC structure for a given cpu.
> >
> > Signed-off-by: Sunil V L <[email protected]>
> > Acked-by: Rafael J. Wysocki <[email protected]>
> > ---
> > arch/riscv/include/asm/acpi.h | 9 ++++++
> > arch/riscv/kernel/acpi.c | 56 +++++++++++++++++++++++++++++++++++
> > 2 files changed, 65 insertions(+)
> >
> > diff --git a/arch/riscv/include/asm/acpi.h b/arch/riscv/include/asm/acpi.h
> > index 111a8ed10af1..8be16c1ef7da 100644
> > --- a/arch/riscv/include/asm/acpi.h
> > +++ b/arch/riscv/include/asm/acpi.h
> > @@ -61,6 +61,10 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
> >
> > int acpi_get_riscv_isa(struct acpi_table_header *table,
> > unsigned int cpu, const char **isa);
> > +
> > +struct acpi_madt_rintc *acpi_cpu_get_madt_rintc(int cpu);
> > +
> > +u32 get_acpi_id_for_cpu(int cpu);
> > #else
> > static inline int acpi_get_riscv_isa(struct acpi_table_header *table,
> > unsigned int cpu, const char **isa)
> > @@ -68,6 +72,11 @@ static inline int acpi_get_riscv_isa(struct acpi_table_header *table,
> > return -EINVAL;
> > }
> >
> > +static inline u32 get_acpi_id_for_cpu(int cpu)
> > +{
> > + return -1;
> > +}
>
> Why do we need this stub? I wouldn't expect non-ACPI code to need an ACPI
> ID.
>
> > +
> > #endif /* CONFIG_ACPI */
> >
> > #endif /*_ASM_ACPI_H*/
> > diff --git a/arch/riscv/kernel/acpi.c b/arch/riscv/kernel/acpi.c
> > index 81d448c41714..8b3d68d8225f 100644
> > --- a/arch/riscv/kernel/acpi.c
> > +++ b/arch/riscv/kernel/acpi.c
> > @@ -24,6 +24,62 @@ EXPORT_SYMBOL(acpi_disabled);
> > int acpi_pci_disabled = 1; /* skip ACPI PCI scan and IRQ initialization */
> > EXPORT_SYMBOL(acpi_pci_disabled);
> >
> > +static struct acpi_madt_rintc cpu_madt_rintc[NR_CPUS];
> > +
> > +static int acpi_parse_madt_rintc(union acpi_subtable_headers *header, const unsigned long end)
> > +{
> > + struct acpi_madt_rintc *rintc = (struct acpi_madt_rintc *)header;
> > + int cpuid;
> > +
> > + if (!(rintc->flags & ACPI_MADT_ENABLED))
> > + return 0;
>
> Why not cache the data even when its disabled? We also cache the flags so
> we can always check later too.
>
Okay, doesn't harm.
> > +
> > + cpuid = riscv_hartid_to_cpuid(rintc->hart_id);
> > + if (cpuid >= 0 && cpuid < NR_CPUS)
>
> What does it mean for the above check to fail? Bad ACPI tables?
>
This can happen when SMP is disabled but platform has more CPUs.
> > + cpu_madt_rintc[cpuid] = *rintc;
> > +
> > + return 0;
> > +}
> > +
> > +static int acpi_init_rintc_array(void)
> > +{
> > + if (acpi_table_parse_madt(ACPI_MADT_TYPE_RINTC, acpi_parse_madt_rintc, 0) > 0)
> > + return 0;
> > +
> > + return -ENODEV;
> > +}
> > +
> > +/*
> > + * Instead of parsing (and freeing) the ACPI table, cache
> > + * the RINTC structures since they are frequently used
> > + * like in cpuinfo.
> > + */
> > +struct acpi_madt_rintc *acpi_cpu_get_madt_rintc(int cpu)
> > +{
> > + static bool rintc_init_done;
> > +
> > + if (!rintc_init_done) {
> > + if (acpi_init_rintc_array()) {
> > + pr_err("No valid RINTC entries exist\n");
> > + return NULL;
> > + }
> > +
> > + rintc_init_done = true;
> > + }
> > +
> > + return &cpu_madt_rintc[cpu];
> > +}
> > +
> > +u32 get_acpi_id_for_cpu(int cpu)
> > +{
> > + struct acpi_madt_rintc *rintc = acpi_cpu_get_madt_rintc(cpu);
> > +
> > + if (!rintc)
> > + return -1;
>
> Is -1 defined as an invalid ACPI ID? I'm wondering if we shouldn't just
> BUG in acpi_init_rintc_array() if we fail to initialize and then we can
> unconditionally return rintc->uid here.
>
Thanks!. Will update this.
On Fri, Mar 03, 2023 at 11:28:21PM +0530, Sunil V L wrote:
> On Fri, Mar 03, 2023 at 05:05:56PM +0100, Andrew Jones wrote:
> > On Fri, Mar 03, 2023 at 07:06:38PM +0530, Sunil V L wrote:
> > > RINTC structures in the MADT provide mapping between the hartid
> > > and the CPU. This is required many times even at run time like
> > > cpuinfo. So, instead of parsing the ACPI table every time, cache
> > > the RINTC structures and provide a function to get the correct
> > > RINTC structure for a given cpu.
> > >
> > > Signed-off-by: Sunil V L <[email protected]>
> > > Acked-by: Rafael J. Wysocki <[email protected]>
> > > ---
> > > arch/riscv/include/asm/acpi.h | 9 ++++++
> > > arch/riscv/kernel/acpi.c | 56 +++++++++++++++++++++++++++++++++++
> > > 2 files changed, 65 insertions(+)
> > >
> > > diff --git a/arch/riscv/include/asm/acpi.h b/arch/riscv/include/asm/acpi.h
> > > index 111a8ed10af1..8be16c1ef7da 100644
> > > --- a/arch/riscv/include/asm/acpi.h
> > > +++ b/arch/riscv/include/asm/acpi.h
> > > @@ -61,6 +61,10 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
> > >
> > > int acpi_get_riscv_isa(struct acpi_table_header *table,
> > > unsigned int cpu, const char **isa);
> > > +
> > > +struct acpi_madt_rintc *acpi_cpu_get_madt_rintc(int cpu);
> > > +
> > > +u32 get_acpi_id_for_cpu(int cpu);
> > > #else
> > > static inline int acpi_get_riscv_isa(struct acpi_table_header *table,
> > > unsigned int cpu, const char **isa)
> > > @@ -68,6 +72,11 @@ static inline int acpi_get_riscv_isa(struct acpi_table_header *table,
> > > return -EINVAL;
> > > }
> > >
> > > +static inline u32 get_acpi_id_for_cpu(int cpu)
> > > +{
> > > + return -1;
> > > +}
> >
> > Why do we need this stub? I wouldn't expect non-ACPI code to need an ACPI
> > ID.
> >
> > > +
> > > #endif /* CONFIG_ACPI */
> > >
> > > #endif /*_ASM_ACPI_H*/
> > > diff --git a/arch/riscv/kernel/acpi.c b/arch/riscv/kernel/acpi.c
> > > index 81d448c41714..8b3d68d8225f 100644
> > > --- a/arch/riscv/kernel/acpi.c
> > > +++ b/arch/riscv/kernel/acpi.c
> > > @@ -24,6 +24,62 @@ EXPORT_SYMBOL(acpi_disabled);
> > > int acpi_pci_disabled = 1; /* skip ACPI PCI scan and IRQ initialization */
> > > EXPORT_SYMBOL(acpi_pci_disabled);
> > >
> > > +static struct acpi_madt_rintc cpu_madt_rintc[NR_CPUS];
> > > +
> > > +static int acpi_parse_madt_rintc(union acpi_subtable_headers *header, const unsigned long end)
> > > +{
> > > + struct acpi_madt_rintc *rintc = (struct acpi_madt_rintc *)header;
> > > + int cpuid;
> > > +
> > > + if (!(rintc->flags & ACPI_MADT_ENABLED))
> > > + return 0;
> >
> > Why not cache the data even when its disabled? We also cache the flags so
> > we can always check later too.
> >
> Okay, doesn't harm.
>
> > > +
> > > + cpuid = riscv_hartid_to_cpuid(rintc->hart_id);
> > > + if (cpuid >= 0 && cpuid < NR_CPUS)
> >
> > What does it mean for the above check to fail? Bad ACPI tables?
> >
> This can happen when SMP is disabled but platform has more CPUs.
Ah yes, NR_CPUS can be too small for the platform. Maybe a comment
explaining that we ignore all additional cpus in the ACPI tables that
we can't manage with the kernel's limits would be helpful here.
Thanks,
drew
On Fri, Mar 03, 2023 at 07:04:52PM +0100, Andrew Jones wrote:
> On Fri, Mar 03, 2023 at 11:28:21PM +0530, Sunil V L wrote:
> > On Fri, Mar 03, 2023 at 05:05:56PM +0100, Andrew Jones wrote:
> > > On Fri, Mar 03, 2023 at 07:06:38PM +0530, Sunil V L wrote:
> > > > RINTC structures in the MADT provide mapping between the hartid
> > > > and the CPU. This is required many times even at run time like
> > > > cpuinfo. So, instead of parsing the ACPI table every time, cache
> > > > the RINTC structures and provide a function to get the correct
> > > > RINTC structure for a given cpu.
> > > >
> > > > Signed-off-by: Sunil V L <[email protected]>
> > > > Acked-by: Rafael J. Wysocki <[email protected]>
> > > > ---
> > > > arch/riscv/include/asm/acpi.h | 9 ++++++
> > > > arch/riscv/kernel/acpi.c | 56 +++++++++++++++++++++++++++++++++++
> > > > 2 files changed, 65 insertions(+)
> > > >
> > > > diff --git a/arch/riscv/include/asm/acpi.h b/arch/riscv/include/asm/acpi.h
> > > > index 111a8ed10af1..8be16c1ef7da 100644
> > > > --- a/arch/riscv/include/asm/acpi.h
> > > > +++ b/arch/riscv/include/asm/acpi.h
> > > > @@ -61,6 +61,10 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
> > > >
> > > > int acpi_get_riscv_isa(struct acpi_table_header *table,
> > > > unsigned int cpu, const char **isa);
> > > > +
> > > > +struct acpi_madt_rintc *acpi_cpu_get_madt_rintc(int cpu);
> > > > +
> > > > +u32 get_acpi_id_for_cpu(int cpu);
> > > > #else
> > > > static inline int acpi_get_riscv_isa(struct acpi_table_header *table,
> > > > unsigned int cpu, const char **isa)
> > > > @@ -68,6 +72,11 @@ static inline int acpi_get_riscv_isa(struct acpi_table_header *table,
> > > > return -EINVAL;
> > > > }
> > > >
> > > > +static inline u32 get_acpi_id_for_cpu(int cpu)
> > > > +{
> > > > + return -1;
> > > > +}
> > >
> > > Why do we need this stub? I wouldn't expect non-ACPI code to need an ACPI
> > > ID.
> > >
> > > > +
> > > > #endif /* CONFIG_ACPI */
> > > >
> > > > #endif /*_ASM_ACPI_H*/
> > > > diff --git a/arch/riscv/kernel/acpi.c b/arch/riscv/kernel/acpi.c
> > > > index 81d448c41714..8b3d68d8225f 100644
> > > > --- a/arch/riscv/kernel/acpi.c
> > > > +++ b/arch/riscv/kernel/acpi.c
> > > > @@ -24,6 +24,62 @@ EXPORT_SYMBOL(acpi_disabled);
> > > > int acpi_pci_disabled = 1; /* skip ACPI PCI scan and IRQ initialization */
> > > > EXPORT_SYMBOL(acpi_pci_disabled);
> > > >
> > > > +static struct acpi_madt_rintc cpu_madt_rintc[NR_CPUS];
> > > > +
> > > > +static int acpi_parse_madt_rintc(union acpi_subtable_headers *header, const unsigned long end)
> > > > +{
> > > > + struct acpi_madt_rintc *rintc = (struct acpi_madt_rintc *)header;
> > > > + int cpuid;
> > > > +
> > > > + if (!(rintc->flags & ACPI_MADT_ENABLED))
> > > > + return 0;
> > >
> > > Why not cache the data even when its disabled? We also cache the flags so
> > > we can always check later too.
> > >
> > Okay, doesn't harm.
> >
On second thought, I would like to keep this check. The reason is, it
is indexed using logical cpuid and OS will not enumerate disabled CPUs.
> > > > +
> > > > + cpuid = riscv_hartid_to_cpuid(rintc->hart_id);
> > > > + if (cpuid >= 0 && cpuid < NR_CPUS)
> > >
> > > What does it mean for the above check to fail? Bad ACPI tables?
> > >
> > This can happen when SMP is disabled but platform has more CPUs.
>
> Ah yes, NR_CPUS can be too small for the platform. Maybe a comment
> explaining that we ignore all additional cpus in the ACPI tables that
> we can't manage with the kernel's limits would be helpful here.
>
Sure.
Thanks,
Sunil
On Fri, Mar 03, 2023 at 04:36:17PM +0100, Andrew Jones wrote:
> On Fri, Mar 03, 2023 at 07:06:33PM +0530, Sunil V L wrote:
> > Enable ACPI core for RISC-V after adding architecture-specific
> > interfaces and header files required to build the ACPI core.
> >
> > 1) Couple of header files are required unconditionally by the ACPI
> > core. Add empty acenv.h and cpu.h header files.
> >
> > 2) If CONFIG_PCI is enabled, a few PCI related interfaces need to
> > be provided by the architecture. Define dummy interfaces for now
> > so that build succeeds. Actual implementation will be added when
> > PCI support is added for ACPI along with external interrupt
> > controller support.
> >
> > 3) A few globals and memory mapping related functions specific
> > to the architecture need to be provided.
> >
> > Signed-off-by: Sunil V L <[email protected]>
> > Acked-by: Rafael J. Wysocki <[email protected]>
> > Reviewed-by: Andrew Jones <[email protected]>
> > ---
> > arch/riscv/Kconfig | 5 +++
> > arch/riscv/include/asm/acenv.h | 11 +++++
> > arch/riscv/include/asm/acpi.h | 61 ++++++++++++++++++++++++++
> > arch/riscv/include/asm/cpu.h | 8 ++++
> > arch/riscv/kernel/Makefile | 2 +
> > arch/riscv/kernel/acpi.c | 80 ++++++++++++++++++++++++++++++++++
> > 6 files changed, 167 insertions(+)
> > create mode 100644 arch/riscv/include/asm/acenv.h
> > create mode 100644 arch/riscv/include/asm/acpi.h
> > create mode 100644 arch/riscv/include/asm/cpu.h
> > create mode 100644 arch/riscv/kernel/acpi.c
> >
> > diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> > index 71754eb32ee6..f3108c7e19d8 100644
> > --- a/arch/riscv/Kconfig
> > +++ b/arch/riscv/Kconfig
> > @@ -12,6 +12,8 @@ config 32BIT
> >
> > config RISCV
> > def_bool y
> > + select ACPI_GENERIC_GSI if ACPI
> > + select ACPI_REDUCED_HARDWARE_ONLY if ACPI
> > select ARCH_ENABLE_HUGEPAGE_MIGRATION if HUGETLB_PAGE && MIGRATION
> > select ARCH_ENABLE_SPLIT_PMD_PTLOCK if PGTABLE_LEVELS > 2
> > select ARCH_ENABLE_THP_MIGRATION if TRANSPARENT_HUGEPAGE
> > @@ -617,6 +619,7 @@ config EFI
> > depends on OF && !XIP_KERNEL
> > depends on MMU
> > default y
> > + select ARCH_SUPPORTS_ACPI if 64BIT
> > select EFI_GENERIC_STUB
> > select EFI_PARAMS_FROM_FDT
> > select EFI_RUNTIME_WRAPPERS
> > @@ -720,3 +723,5 @@ source "drivers/cpufreq/Kconfig"
> > endmenu # "CPU Power Management"
> >
> > source "arch/riscv/kvm/Kconfig"
> > +
> > +source "drivers/acpi/Kconfig"
>
> The above Kconfig hunks don't apply on the IPI improvement base. The
> second hunk also looks weird with the select under the default.
>
Just following up here; as Sunil pointed out in chat, the base is
latest master with the IPI improvement rebased. I was using the
last IPI improvement branch. So that explains the problem I had
applying this and the weirdness I was seeing with the Kconfig
lines (select/default) as compared to v2.
Thanks,
drew
On Fri, Mar 03, 2023 at 07:06:33PM +0530, Sunil V L wrote:
> Enable ACPI core for RISC-V after adding architecture-specific
> interfaces and header files required to build the ACPI core.
>
> 1) Couple of header files are required unconditionally by the ACPI
> core. Add empty acenv.h and cpu.h header files.
>
> 2) If CONFIG_PCI is enabled, a few PCI related interfaces need to
> be provided by the architecture. Define dummy interfaces for now
> so that build succeeds. Actual implementation will be added when
> PCI support is added for ACPI along with external interrupt
> controller support.
>
> 3) A few globals and memory mapping related functions specific
> to the architecture need to be provided.
>
> Signed-off-by: Sunil V L <[email protected]>
> Acked-by: Rafael J. Wysocki <[email protected]>
> Reviewed-by: Andrew Jones <[email protected]>
> diff --git a/arch/riscv/include/asm/acenv.h b/arch/riscv/include/asm/acenv.h
> new file mode 100644
> index 000000000000..22123c5a4883
> --- /dev/null
> +++ b/arch/riscv/include/asm/acenv.h
> @@ -0,0 +1,11 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * RISC-V specific ACPICA environments and implementation
> + */
> +
> +#ifndef _ASM_ACENV_H
> +#define _ASM_ACENV_H
> +
> +/* It is required unconditionally by ACPI core */
Think I pointed out on v1 that this comment doesn't really make any
sense. s/It/This header/.
> +
> +#endif /* _ASM_ACENV_H */
> diff --git a/arch/riscv/include/asm/acpi.h b/arch/riscv/include/asm/acpi.h
> new file mode 100644
> index 000000000000..0b52a190f71a
> --- /dev/null
> +++ b/arch/riscv/include/asm/acpi.h
> @@ -0,0 +1,61 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (C) 2013-2014, Linaro Ltd.
> + * Author: Al Stone <[email protected]>
> + * Author: Graeme Gregory <[email protected]>
> + * Author: Hanjun Guo <[email protected]>
> + *
> + * Copyright (C) 2021-2023, Ventana Micro Systems Inc.
> + * Author: Sunil V L <[email protected]>
> + */
> +
> +#ifndef _ASM_ACPI_H
> +#define _ASM_ACPI_H
> +
> +/* Basic configuration for ACPI */
> +#ifdef CONFIG_ACPI
> +
> +/* ACPI table mapping after acpi_permanent_mmap is set */
> +void *acpi_os_ioremap(acpi_physical_address phys, acpi_size size);
> +#define acpi_os_ioremap acpi_os_ioremap
> +
> +#define acpi_strict 1 /* No out-of-spec workarounds on RISC-V */
^^^
Kinda weird whitespace here, my editor noticed and my OCD won't let it
go unsaid :/ You used a tab before similar use comments later in this
patch.
> +extern int acpi_disabled;
> +extern int acpi_noirq;
> +extern int acpi_pci_disabled;
> +
> +static inline void disable_acpi(void)
> +{
> + acpi_disabled = 1;
> + acpi_pci_disabled = 1;
> + acpi_noirq = 1;
> +}
> +
> +static inline void enable_acpi(void)
> +{
> + acpi_disabled = 0;
> + acpi_pci_disabled = 0;
> + acpi_noirq = 0;
> +}
> +
> +/*
> + * The ACPI processor driver for ACPI core code needs this macro
> + * to find out this cpu was already mapped (mapping from CPU hardware
^
missing word "whether"
> diff --git a/arch/riscv/include/asm/cpu.h b/arch/riscv/include/asm/cpu.h
> new file mode 100644
> index 000000000000..ea1a88b3d5f2
> --- /dev/null
> +++ b/arch/riscv/include/asm/cpu.h
> @@ -0,0 +1,8 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +
> +#ifndef _ASM_CPU_H
> +#define _ASM_CPU_H
> +
> +/* It is required unconditionally by ACPI core */
Same comment here, what is "it"?
> +
> +#endif /* _ASM_CPU_H */
> diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
> index 67f542be1bea..f979dc8cf47d 100644
> --- a/arch/riscv/kernel/Makefile
> +++ b/arch/riscv/kernel/Makefile
> @@ -90,3 +90,5 @@ obj-$(CONFIG_EFI) += efi.o
> obj-$(CONFIG_COMPAT) += compat_syscall_table.o
> obj-$(CONFIG_COMPAT) += compat_signal.o
> obj-$(CONFIG_COMPAT) += compat_vdso/
> +
> +obj-$(CONFIG_ACPI) += acpi.o
This file appears to be tab aligned (at least the other lines in the
diff are), so please tab align this one too.
Those are all nitpick things though, so w/ 'em fixed:
Reviewed-by: Conor Dooley <[email protected]>
Cheers,
Conor.
On Fri, Mar 03, 2023 at 07:06:39PM +0530, Sunil V L wrote:
> On ACPI based systems, the information about the hart
> like ISA is provided by the RISC-V Hart Capabilities Table (RHCT).
> Enable filling up hwcap structure based on the information in RHCT.
>
> Signed-off-by: Sunil V L <[email protected]>
> Acked-by: Rafael J. Wysocki <[email protected]>
With Drew's split out of the riscv_of_processor_hartid() removal and his
acpi_get_riscv_isa()-takes-a-cpu suggestion:
Reviewed-by: Conor Dooley <[email protected]>
Cheers,
Conor.
On Fri, Mar 03, 2023 at 07:06:40PM +0530, Sunil V L wrote:
> On ACPI based platforms, few details like ISA need to be read
> from the ACPI table. Enable cpuinfo on ACPI based systems.
>
> Signed-off-by: Sunil V L <[email protected]>
> Acked-by: Rafael J. Wysocki <[email protected]>
> ---
> arch/riscv/kernel/cpu.c | 27 +++++++++++++++++++--------
> 1 file changed, 19 insertions(+), 8 deletions(-)
>
> diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
> index 8400f0cc9704..80101bf77dab 100644
> --- a/arch/riscv/kernel/cpu.c
> +++ b/arch/riscv/kernel/cpu.c
> @@ -3,10 +3,12 @@
> * Copyright (C) 2012 Regents of the University of California
> */
>
> +#include <linux/acpi.h>
> #include <linux/cpu.h>
> #include <linux/init.h>
> #include <linux/seq_file.h>
> #include <linux/of.h>
> +#include <asm/acpi.h>
> #include <asm/csr.h>
> #include <asm/hwcap.h>
> #include <asm/sbi.h>
> @@ -283,23 +285,32 @@ static void c_stop(struct seq_file *m, void *v)
> static int c_show(struct seq_file *m, void *v)
> {
> unsigned long cpu_id = (unsigned long)v - 1;
> - struct device_node *node = of_get_cpu_node(cpu_id, NULL);
> struct riscv_cpuinfo *ci = per_cpu_ptr(&riscv_cpuinfo, cpu_id);
> + struct device_node *node;
> const char *compat, *isa;
>
> seq_printf(m, "processor\t: %lu\n", cpu_id);
> seq_printf(m, "hart\t\t: %lu\n", cpuid_to_hartid_map(cpu_id));
> - if (!of_property_read_string(node, "riscv,isa", &isa))
> - print_isa(m, isa);
> - print_mmu(m);
> - if (!of_property_read_string(node, "compatible", &compat)
> - && strcmp(compat, "riscv"))
> - seq_printf(m, "uarch\t\t: %s\n", compat);
> +
> + if (acpi_disabled) {
> + node = of_get_cpu_node(cpu_id, NULL);
> + if (!of_property_read_string(node, "riscv,isa", &isa))
> + print_isa(m, isa);
> + print_mmu(m);
> + if (!of_property_read_string(node, "compatible", &compat) &&
> + strcmp(compat, "riscv"))
> + seq_printf(m, "uarch\t\t: %s\n", compat);
> + of_node_put(node);
While you're touching this stuff, would you mind decorating it with some
whitespace between if statements?
> + } else {
> + if (!acpi_get_riscv_isa(NULL, get_acpi_id_for_cpu(cpu_id), &isa))
> + print_isa(m, isa);
> + print_mmu(m);
I assume ACPI has no equivalent of the compatible from which to generate
uarch?
A note as to why this is not present in the commit message would likely
be helpful to us ACPI-heathens.
> + }
> +
> seq_printf(m, "mvendorid\t: 0x%lx\n", ci->mvendorid);
> seq_printf(m, "marchid\t\t: 0x%lx\n", ci->marchid);
> seq_printf(m, "mimpid\t\t: 0x%lx\n", ci->mimpid);
> seq_puts(m, "\n");
> - of_node_put(node);
>
> return 0;
> }
> --
> 2.34.1
>
On Fri, Mar 03, 2023 at 07:06:41PM +0530, Sunil V L wrote:
> Add support for initializing the RISC-V INTC driver on ACPI
> platforms.
>
> Signed-off-by: Sunil V L <[email protected]>
> Acked-by: Rafael J. Wysocki <[email protected]>
> Reviewed-by: Andrew Jones <[email protected]>
> ---
> drivers/irqchip/irq-riscv-intc.c | 77 +++++++++++++++++++++++++++-----
> 1 file changed, 65 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/irqchip/irq-riscv-intc.c b/drivers/irqchip/irq-riscv-intc.c
> index f229e3e66387..f522510dc1f3 100644
> --- a/drivers/irqchip/irq-riscv-intc.c
> +++ b/drivers/irqchip/irq-riscv-intc.c
> @@ -6,6 +6,7 @@
> */
>
> #define pr_fmt(fmt) "riscv-intc: " fmt
> +#include <linux/acpi.h>
> #include <linux/atomic.h>
> #include <linux/bits.h>
> #include <linux/cpu.h>
> @@ -112,6 +113,30 @@ static struct fwnode_handle *riscv_intc_hwnode(void)
> return intc_domain->fwnode;
> }
>
> +static int __init riscv_intc_init_common(struct fwnode_handle *fn)
> +{
> + int rc;
> +
> + intc_domain = irq_domain_create_linear(fn, BITS_PER_LONG,
> + &riscv_intc_domain_ops, NULL);
> + if (!intc_domain) {
> + pr_err("unable to add IRQ domain\n");
> + return -ENXIO;
> + }
> +
> + rc = set_handle_irq(&riscv_intc_irq);
> + if (rc) {
> + pr_err("failed to set irq handler\n");
> + return rc;
> + }
> +
> + riscv_set_intc_hwnode_fn(riscv_intc_hwnode);
> +
> + pr_info("%d local interrupts mapped\n", BITS_PER_LONG);
> +
> + return 0;
> +}
> +
> static int __init riscv_intc_init(struct device_node *node,
> struct device_node *parent)
> {
> @@ -133,24 +158,52 @@ static int __init riscv_intc_init(struct device_node *node,
> if (riscv_hartid_to_cpuid(hartid) != smp_processor_id())
> return 0;
>
> - intc_domain = irq_domain_add_linear(node, BITS_PER_LONG,
> - &riscv_intc_domain_ops, NULL);
> - if (!intc_domain) {
> - pr_err("unable to add IRQ domain\n");
> - return -ENXIO;
> - }
> -
> - rc = set_handle_irq(&riscv_intc_irq);
> + rc = riscv_intc_init_common(of_node_to_fwnode(node));
> if (rc) {
> - pr_err("failed to set irq handler\n");
> + pr_err("failed to initialize INTC\n");
The early return paths from riscv_intc_init_common() all print
something, is also printing here redundant?
This seems fine to me otherwise though,
Reviewed-by: Conor Dooley <[email protected]>
Thanks,
Conor.
> return rc;
> }
>
> - riscv_set_intc_hwnode_fn(riscv_intc_hwnode);
> + return 0;
> +}
>
> - pr_info("%d local interrupts mapped\n", BITS_PER_LONG);
> +IRQCHIP_DECLARE(riscv, "riscv,cpu-intc", riscv_intc_init);
> +
> +#ifdef CONFIG_ACPI
> +
> +static int __init riscv_intc_acpi_init(union acpi_subtable_headers *header,
> + const unsigned long end)
> +{
> + int rc;
> + struct fwnode_handle *fn;
> + struct acpi_madt_rintc *rintc;
> +
> + rintc = (struct acpi_madt_rintc *)header;
> +
> + /*
> + * The ACPI MADT will have one INTC for each CPU (or HART)
> + * so riscv_intc_acpi_init() function will be called once
> + * for each INTC. We only do INTC initialization
> + * for the INTC belonging to the boot CPU (or boot HART).
> + */
> + if (riscv_hartid_to_cpuid(rintc->hart_id) != smp_processor_id())
> + return 0;
> +
> + fn = irq_domain_alloc_named_fwnode("RISCV-INTC");
> + if (!fn) {
> + pr_err("unable to allocate INTC FW node\n");
> + return -ENOMEM;
> + }
> +
> + rc = riscv_intc_init_common(fn);
> + if (rc) {
> + pr_err("failed to initialize INTC\n");
> + return rc;
> + }
>
> return 0;
> }
>
> -IRQCHIP_DECLARE(riscv, "riscv,cpu-intc", riscv_intc_init);
> +IRQCHIP_ACPI_DECLARE(riscv_intc, ACPI_MADT_TYPE_RINTC, NULL,
> + ACPI_MADT_RINTC_VERSION_V1, riscv_intc_acpi_init);
> +#endif
> --
> 2.34.1
>
On Fri, Mar 03, 2023 at 07:06:42PM +0530, Sunil V L wrote:
> Refactor the timer init function such that few things can be
> shared by both DT and ACPI based platforms.
>
> Co-developed-by: Anup Patel <[email protected]>
> Signed-off-by: Anup Patel <[email protected]>
> Signed-off-by: Sunil V L <[email protected]>
> Acked-by: Rafael J. Wysocki <[email protected]>
> Reviewed-by: Andrew Jones <[email protected]>
> ---
> drivers/clocksource/timer-riscv.c | 81 +++++++++++++++----------------
> 1 file changed, 40 insertions(+), 41 deletions(-)
>
> diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c
> index 5f0f10c7e222..cecc4662293b 100644
> --- a/drivers/clocksource/timer-riscv.c
> +++ b/drivers/clocksource/timer-riscv.c
> @@ -124,61 +124,28 @@ static irqreturn_t riscv_timer_interrupt(int irq, void *dev_id)
> return IRQ_HANDLED;
> }
>
> -static int __init riscv_timer_init_dt(struct device_node *n)
> +static int __init riscv_timer_init_common(void)
> {
> - int cpuid, error;
> - unsigned long hartid;
> - struct device_node *child;
> + int error;
> struct irq_domain *domain;
> + struct fwnode_handle *intc_fwnode = riscv_get_intc_hwnode();
>
> - error = riscv_of_processor_hartid(n, &hartid);
> - if (error < 0) {
> - pr_warn("Not valid hartid for node [%pOF] error = [%lu]\n",
> - n, hartid);
> - return error;
> - }
> -
> - cpuid = riscv_hartid_to_cpuid(hartid);
> - if (cpuid < 0) {
> - pr_warn("Invalid cpuid for hartid [%lu]\n", hartid);
> - return cpuid;
> - }
> -
> - if (cpuid != smp_processor_id())
> - return 0;
> -
> - child = of_find_compatible_node(NULL, NULL, "riscv,timer");
> - if (child) {
> - riscv_timer_cannot_wake_cpu = of_property_read_bool(child,
> - "riscv,timer-cannot-wake-cpu");
> - of_node_put(child);
> - }
> -
> - domain = NULL;
> - child = of_get_compatible_child(n, "riscv,cpu-intc");
> - if (!child) {
> - pr_err("Failed to find INTC node [%pOF]\n", n);
> - return -ENODEV;
> - }
> - domain = irq_find_host(child);
> - of_node_put(child);
> + domain = irq_find_matching_fwnode(intc_fwnode, DOMAIN_BUS_ANY);
> if (!domain) {
> - pr_err("Failed to find IRQ domain for node [%pOF]\n", n);
> + pr_err("Failed to find irq_domain for INTC node [%pfwP]\n",
> + intc_fwnode);
> return -ENODEV;
> }
>
> riscv_clock_event_irq = irq_create_mapping(domain, RV_IRQ_TIMER);
> if (!riscv_clock_event_irq) {
> - pr_err("Failed to map timer interrupt for node [%pOF]\n", n);
> + pr_err("Failed to map timer interrupt for node [%pfwP]\n", intc_fwnode);
> return -ENODEV;
> }
>
> - pr_info("%s: Registering clocksource cpuid [%d] hartid [%lu]\n",
> - __func__, cpuid, hartid);
> error = clocksource_register_hz(&riscv_clocksource, riscv_timebase);
> if (error) {
> - pr_err("RISCV timer register failed [%d] for cpu = [%d]\n",
> - error, cpuid);
> + pr_err("RISCV timer registration failed [%d]\n", error);
> return error;
> }
>
> @@ -207,4 +174,36 @@ static int __init riscv_timer_init_dt(struct device_node *n)
> return error;
> }
>
> +static int __init riscv_timer_init_dt(struct device_node *n)
> +{
> + int cpuid, error;
> + unsigned long hartid;
> + struct device_node *child;
> +
> + error = riscv_of_processor_hartid(n, &hartid);
> + if (error < 0) {
> + pr_warn("Invalid hartid for node [%pOF] error = [%lu]\n",
> + n, hartid);
I know this was there initially, but why is this (and the one below) a
pr_warn() if we're aborting the init if we hit the condition? :thinking:
It's not your doing though, so:
Reviewed-by: Conor Dooley <[email protected]>
Thanks,
Conor.
> + return error;
> + }
> +
> + cpuid = riscv_hartid_to_cpuid(hartid);
> + if (cpuid < 0) {
> + pr_warn("Invalid cpuid for hartid [%lu]\n", hartid);
> + return cpuid;
> + }
> +
> + if (cpuid != smp_processor_id())
> + return 0;
> +
> + child = of_find_compatible_node(NULL, NULL, "riscv,timer");
> + if (child) {
> + riscv_timer_cannot_wake_cpu = of_property_read_bool(child,
> + "riscv,timer-cannot-wake-cpu");
> + of_node_put(child);
> + }
> +
> + return riscv_timer_init_common();
> +}
> +
> TIMER_OF_DECLARE(riscv_timer, "riscv", riscv_timer_init_dt);
> --
> 2.34.1
>
On Fri, Mar 03, 2023 at 07:06:43PM +0530, Sunil V L wrote:
> Initialize the timer driver based on RHCT table on ACPI based
> platforms.
>
> Signed-off-by: Sunil V L <[email protected]>
> Acked-by: Rafael J. Wysocki <[email protected]>
> Reviewed-by: Andrew Jones <[email protected]>
The SBI spec allows for implementations where the timer cannot wake the
cpu. You previously said "We have plans to add a flag in RHCT. But that
still needs approval.", so could you please convert this to a more
concrete wording and put the explanation for why this is missing into
the commit message?
Cheers,
Conor.
> ---
> drivers/clocksource/timer-riscv.c | 11 +++++++++++
> 1 file changed, 11 insertions(+)
>
> diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c
> index cecc4662293b..da3071b387eb 100644
> --- a/drivers/clocksource/timer-riscv.c
> +++ b/drivers/clocksource/timer-riscv.c
> @@ -10,6 +10,7 @@
>
> #define pr_fmt(fmt) "riscv-timer: " fmt
>
> +#include <linux/acpi.h>
> #include <linux/clocksource.h>
> #include <linux/clockchips.h>
> #include <linux/cpu.h>
> @@ -207,3 +208,13 @@ static int __init riscv_timer_init_dt(struct device_node *n)
> }
>
> TIMER_OF_DECLARE(riscv_timer, "riscv", riscv_timer_init_dt);
> +
> +#ifdef CONFIG_ACPI
> +static int __init riscv_timer_acpi_init(struct acpi_table_header *table)
> +{
> + return riscv_timer_init_common();
> +}
> +
> +TIMER_ACPI_DECLARE(aclint_mtimer, ACPI_SIG_RHCT, riscv_timer_acpi_init);
> +
> +#endif
> --
> 2.34.1
>
On Fri, Mar 03, 2023 at 07:06:44PM +0530, Sunil V L wrote:
> On ACPI based platforms, timer related information is
> available in RHCT. Add ACPI based probe support to the
> timer initialization.
>
> Signed-off-by: Sunil V L <[email protected]>
> Acked-by: Rafael J. Wysocki <[email protected]>
> Reviewed-by: Andrew Jones <[email protected]>
> ---
> arch/riscv/kernel/time.c | 23 +++++++++++++++++------
> 1 file changed, 17 insertions(+), 6 deletions(-)
>
> diff --git a/arch/riscv/kernel/time.c b/arch/riscv/kernel/time.c
> index babaf3b48ba8..2c29543549c3 100644
> --- a/arch/riscv/kernel/time.c
> +++ b/arch/riscv/kernel/time.c
> @@ -4,6 +4,7 @@
> * Copyright (C) 2017 SiFive
> */
>
> +#include <linux/acpi.h>
> #include <linux/of_clk.h>
> #include <linux/clockchips.h>
> #include <linux/clocksource.h>
> @@ -18,17 +19,27 @@ EXPORT_SYMBOL_GPL(riscv_timebase);
> void __init time_init(void)
> {
> struct device_node *cpu;
> + struct acpi_table_rhct *rhct;
> + acpi_status status;
> u32 prop;
>
> - cpu = of_find_node_by_path("/cpus");
> - if (!cpu || of_property_read_u32(cpu, "timebase-frequency", &prop))
> - panic(KERN_WARNING "RISC-V system with no 'timebase-frequency' in DTS\n");
> - of_node_put(cpu);
> - riscv_timebase = prop;
> + if (acpi_disabled) {
> + cpu = of_find_node_by_path("/cpus");
> + if (!cpu || of_property_read_u32(cpu, "timebase-frequency", &prop))
> + panic("RISC-V system with no 'timebase-frequency' in DTS\n");
I appreciate that it was like this before, but a newline here (and in
the corresponding spot below) would be nice.
That's a minor nit though, so:
Reviewed-by: Conor Dooley <[email protected]>
Thanks,
Conor.
> + of_node_put(cpu);
> + riscv_timebase = prop;
> + of_clk_init(NULL);
> + } else {
> + status = acpi_get_table(ACPI_SIG_RHCT, 0, (struct acpi_table_header **)&rhct);
> + if (ACPI_FAILURE(status))
> + panic("RISC-V ACPI system with no RHCT table\n");
> + riscv_timebase = rhct->time_base_freq;
> + acpi_put_table((struct acpi_table_header *)rhct);
> + }
>
> lpj_fine = riscv_timebase / HZ;
>
> - of_clk_init(NULL);
> timer_probe();
>
> tick_setup_hrtimer_broadcast();
> --
> 2.34.1
>
On Fri, Mar 03, 2023 at 07:06:45PM +0530, Sunil V L wrote:
> Initialize the ACPI core for RISC-V during boot.
>
> ACPI tables and interpreter are initialized based on
> the information passed from the firmware and the value of
> the kernel parameter 'acpi'.
>
> With ACPI support added for RISC-V, the kernel parameter 'acpi'
> is also supported on RISC-V. Hence, update the documentation.
>
> Signed-off-by: Sunil V L <[email protected]>
> Acked-by: Rafael J. Wysocki <[email protected]>
> Reviewed-by: Andrew Jones <[email protected]>
> ---
> +static int __init acpi_fadt_sanity_check(void)
> +{
> + struct acpi_table_header *table;
> + struct acpi_table_fadt *fadt;
> + acpi_status status;
> + int ret = 0;
> +
> + /*
> + * FADT is required on riscv; retrieve it to check its presence
> + * and carry out revision and ACPI HW reduced compliancy tests
> + */
> + status = acpi_get_table(ACPI_SIG_FADT, 0, &table);
> + if (ACPI_FAILURE(status)) {
> + const char *msg = acpi_format_exception(status);
> +
> + pr_err("Failed to get FADT table, %s\n", msg);
> + return -ENODEV;
> + }
> +
> + fadt = (struct acpi_table_fadt *)table;
> +
> + /*
> + * Revision in table header is the FADT Major revision, and there
> + * is a minor revision of FADT.
What is the point of this part of the comment? Isn't it obvious from the
below code that you expect a major and minor revision?
If feel like you're trying to make a point in it, but the point has been
lost :/
> + *
> + * TODO: Currently, we check for 6.5 as the minimum version to check
> + * for HW_REDUCED flag. However, once RISC-V updates are released in
> + * the ACPI spec, we need to update this check for exact minor revision
> + */
> + if (table->revision < 6 || (table->revision == 6 && fadt->minor_revision < 5)) {
> + pr_err(FW_BUG "Unsupported FADT revision %d.%d, should be 6.5+\n",
> + table->revision, fadt->minor_revision);
> + }
> +
> + if (!(fadt->flags & ACPI_FADT_HW_REDUCED)) {
> + pr_err("FADT not ACPI hardware reduced compliant\n");
> + ret = -EINVAL;
> + }
> +
> + /*
> + * acpi_get_table() creates FADT table mapping that
> + * should be released after parsing and before resuming boot
> + */
> + acpi_put_table(table);
> + return ret;
> +}
> diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
> index 2d45a416d283..7b2b065a9f70 100644
> --- a/arch/riscv/kernel/setup.c
> +++ b/arch/riscv/kernel/setup.c
> @@ -8,6 +8,7 @@
> * Nick Kossifidis <[email protected]>
> */
>
> +#include <linux/acpi.h>
> #include <linux/init.h>
> #include <linux/mm.h>
> #include <linux/memblock.h>
> @@ -276,14 +277,22 @@ void __init setup_arch(char **cmdline_p)
>
> efi_init();
> paging_init();
> -#if IS_ENABLED(CONFIG_BUILTIN_DTB)
> - unflatten_and_copy_device_tree();
> -#else
> - if (early_init_dt_verify(__va(XIP_FIXUP(dtb_early_pa))))
> - unflatten_device_tree();
> - else
> - pr_err("No DTB found in kernel mappings\n");
> -#endif
> +
> + /* Parse the ACPI tables for possible boot-time configuration */
> + acpi_boot_table_init();
> + if (acpi_disabled) {
> + if (IS_ENABLED(CONFIG_BUILTIN_DTB)) {
> + unflatten_and_copy_device_tree();
> + } else {
> + if (early_init_dt_verify(__va(XIP_FIXUP(dtb_early_pa))))
> + unflatten_device_tree();
> + else
> + pr_err("No DTB found in kernel mappings\n");
> + }
> + } else {
> + early_init_dt_verify(__va(XIP_FIXUP(dtb_early_pa)));
> + }
> +
> early_init_fdt_scan_reserved_mem();
> misc_mem_init();
Thanks for removing the ifdeffery :)
Acked-by: Conor Dooley <[email protected]>
Thanks,
Conor.
Reviewed-by: Conor Dooley <[email protected]>
Hey Sunil,
On Fri, Mar 03, 2023 at 07:06:27PM +0530, Sunil V L wrote:
> This patch series enables the basic ACPI infrastructure for RISC-V.
> Supporting external interrupt controllers is in progress and hence it is
> tested using poll based HVC SBI console and RAM disk.
>
> The first patch in this series is one of the patch from Jisheng's
> series [1] which is not merged yet. This patch is required to support
> ACPI since efi_init() which gets called before sbi_init() can enable
> static branches and hits a panic.
>
> Patch 2 and 3 are ACPICA patches which are not merged into acpica yet
> but a PR is raised already.
>
> Below are two ECRs approved by ASWG.
> RINTC - https://drive.google.com/file/d/1R6k4MshhN3WTT-hwqAquu5nX6xSEqK2l/view
> RHCT - https://drive.google.com/file/d/1nP3nFiH4jkPMp6COOxP6123DCZKR-tia/view
>
> The series depends on Anup's IPI improvement series [2].
>
> [1] https://lore.kernel.org/all/[email protected]/
> [2] https://lore.kernel.org/lkml/[email protected]/T/
Building a clang-15 allmodconfig (I didn't try gcc) with this series, and
Anup's IPI bits, results in a broken build, due to failings in cmpxchg:
/stuff/linux/drivers/platform/surface/aggregator/controller.c:61:25: error: call to __compiletime_assert_335 declared with 'error' attribute: BUILD_BUG failed
while (unlikely((ret = cmpxchg(&c->value, old, new)) != old)) {
^
/stuff/linux/include/linux/atomic/atomic-instrumented.h:1916:2: note: expanded from macro 'cmpxchg'
arch_cmpxchg(__ai_ptr, __VA_ARGS__); \
^
/stuff/linux/arch/riscv/include/asm/cmpxchg.h:344:23: note: expanded from macro 'arch_cmpxchg'
(__typeof__(*(ptr))) __cmpxchg((ptr), \
^
/stuff/linux/arch/riscv/include/asm/cmpxchg.h:335:3: note: expanded from macro '__cmpxchg'
BUILD_BUG(); \
^
note: (skipping 3 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
/stuff/linux/include/linux/compiler_types.h:385:2: note: expanded from macro '_compiletime_assert'
__compiletime_assert(condition, msg, prefix, suffix)
^
/stuff/linux/include/linux/compiler_types.h:378:4: note: expanded from macro '__compiletime_assert'
prefix ## suffix(); \
^
<scratch space>:69:1: note: expanded from here
__compiletime_assert_335
^
/stuff/linux/drivers/platform/surface/aggregator/controller.c:61:25: error: call to __compiletime_assert_335 declared with 'error' attribute: BUILD_BUG failed
/stuff/linux/include/linux/atomic/atomic-instrumented.h:1916:2: note: expanded from macro 'cmpxchg'
arch_cmpxchg(__ai_ptr, __VA_ARGS__); \
^
/stuff/linux/arch/riscv/include/asm/cmpxchg.h:344:23: note: expanded from macro 'arch_cmpxchg'
(__typeof__(*(ptr))) __cmpxchg((ptr), \
^
/stuff/linux/arch/riscv/include/asm/cmpxchg.h:335:3: note: expanded from macro '__cmpxchg'
BUILD_BUG(); \
^
note: (skipping 3 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
/stuff/linux/include/linux/compiler_types.h:385:2: note: expanded from macro '_compiletime_assert'
__compiletime_assert(condition, msg, prefix, suffix)
^
/stuff/linux/include/linux/compiler_types.h:378:4: note: expanded from macro '__compiletime_assert'
prefix ## suffix(); \
^
<scratch space>:69:1: note: expanded from here
__compiletime_assert_335
^
/stuff/linux/drivers/platform/surface/aggregator/controller.c:61:25: error: call to __compiletime_assert_335 declared with 'error' attribute: BUILD_BUG failed
/stuff/linux/include/linux/atomic/atomic-instrumented.h:1916:2: note: expanded from macro 'cmpxchg'
arch_cmpxchg(__ai_ptr, __VA_ARGS__); \
^
/stuff/linux/arch/riscv/include/asm/cmpxchg.h:344:23: note: expanded from macro 'arch_cmpxchg'
(__typeof__(*(ptr))) __cmpxchg((ptr), \
^
/stuff/linux/arch/riscv/include/asm/cmpxchg.h:335:3: note: expanded from macro '__cmpxchg'
BUILD_BUG(); \
^
note: (skipping 3 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
/stuff/linux/include/linux/compiler_types.h:385:2: note: expanded from macro '_compiletime_assert'
__compiletime_assert(condition, msg, prefix, suffix)
^
/stuff/linux/include/linux/compiler_types.h:378:4: note: expanded from macro '__compiletime_assert'
prefix ## suffix(); \
^
<scratch space>:69:1: note: expanded from here
__compiletime_assert_335
^
/stuff/linux/drivers/platform/surface/aggregator/controller.c:61:25: error: call to __compiletime_assert_335 declared with 'error' attribute: BUILD_BUG failed
/stuff/linux/include/linux/atomic/atomic-instrumented.h:1916:2: note: expanded from macro 'cmpxchg'
arch_cmpxchg(__ai_ptr, __VA_ARGS__); \
^
/stuff/linux/arch/riscv/include/asm/cmpxchg.h:344:23: note: expanded from macro 'arch_cmpxchg'
(__typeof__(*(ptr))) __cmpxchg((ptr), \
^
/stuff/linux/arch/riscv/include/asm/cmpxchg.h:335:3: note: expanded from macro '__cmpxchg'
BUILD_BUG(); \
^
note: (skipping 3 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
/stuff/linux/include/linux/compiler_types.h:385:2: note: expanded from macro '_compiletime_assert'
__compiletime_assert(condition, msg, prefix, suffix)
^
/stuff/linux/include/linux/compiler_types.h:378:4: note: expanded from macro '__compiletime_assert'
prefix ## suffix(); \
^
<scratch space>:69:1: note: expanded from here
__compiletime_assert_335
^
/stuff/linux/drivers/platform/surface/aggregator/controller.c:61:25: error: call to __compiletime_assert_335 declared with 'error' attribute: BUILD_BUG failed
/stuff/linux/include/linux/atomic/atomic-instrumented.h:1916:2: note: expanded from macro 'cmpxchg'
arch_cmpxchg(__ai_ptr, __VA_ARGS__); \
^
/stuff/linux/arch/riscv/include/asm/cmpxchg.h:344:23: note: expanded from macro 'arch_cmpxchg'
(__typeof__(*(ptr))) __cmpxchg((ptr), \
^
/stuff/linux/arch/riscv/include/asm/cmpxchg.h:335:3: note: expanded from macro '__cmpxchg'
BUILD_BUG(); \
^
note: (skipping 3 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
/stuff/linux/include/linux/compiler_types.h:385:2: note: expanded from macro '_compiletime_assert'
__compiletime_assert(condition, msg, prefix, suffix)
^
/stuff/linux/include/linux/compiler_types.h:378:4: note: expanded from macro '__compiletime_assert'
prefix ## suffix(); \
^
<scratch space>:69:1: note: expanded from here
__compiletime_assert_335
^
/stuff/linux/drivers/platform/surface/aggregator/controller.c:61:25: error: call to __compiletime_assert_335 declared with 'error' attribute: BUILD_BUG failed
/stuff/linux/include/linux/atomic/atomic-instrumented.h:1916:2: note: expanded from macro 'cmpxchg'
arch_cmpxchg(__ai_ptr, __VA_ARGS__); \
^
/stuff/linux/arch/riscv/include/asm/cmpxchg.h:344:23: note: expanded from macro 'arch_cmpxchg'
(__typeof__(*(ptr))) __cmpxchg((ptr), \
^
/stuff/linux/arch/riscv/include/asm/cmpxchg.h:335:3: note: expanded from macro '__cmpxchg'
BUILD_BUG(); \
^
note: (skipping 3 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
/stuff/linux/include/linux/compiler_types.h:385:2: note: expanded from macro '_compiletime_assert'
__compiletime_assert(condition, msg, prefix, suffix)
^
/stuff/linux/include/linux/compiler_types.h:378:4: note: expanded from macro '__compiletime_assert'
prefix ## suffix(); \
^
<scratch space>:69:1: note: expanded from here
__compiletime_assert_335
^
/stuff/linux/drivers/platform/surface/aggregator/controller.c:61:25: error: call to __compiletime_assert_335 declared with 'error' attribute: BUILD_BUG failed
/stuff/linux/include/linux/atomic/atomic-instrumented.h:1916:2: note: expanded from macro 'cmpxchg'
arch_cmpxchg(__ai_ptr, __VA_ARGS__); \
^
/stuff/linux/arch/riscv/include/asm/cmpxchg.h:344:23: note: expanded from macro 'arch_cmpxchg'
(__typeof__(*(ptr))) __cmpxchg((ptr), \
^
/stuff/linux/arch/riscv/include/asm/cmpxchg.h:335:3: note: expanded from macro '__cmpxchg'
BUILD_BUG(); \
^
note: (skipping 3 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
/stuff/linux/include/linux/compiler_types.h:385:2: note: expanded from macro '_compiletime_assert'
__compiletime_assert(condition, msg, prefix, suffix)
^
/stuff/linux/include/linux/compiler_types.h:378:4: note: expanded from macro '__compiletime_assert'
prefix ## suffix(); \
^
<scratch space>:69:1: note: expanded from here
__compiletime_assert_335
^
/stuff/linux/drivers/platform/surface/aggregator/controller.c:61:25: error: call to __compiletime_assert_335 declared with 'error' attribute: BUILD_BUG failed
/stuff/linux/include/linux/atomic/atomic-instrumented.h:1916:2: note: expanded from macro 'cmpxchg'
arch_cmpxchg(__ai_ptr, __VA_ARGS__); \
^
/stuff/linux/arch/riscv/include/asm/cmpxchg.h:344:23: note: expanded from macro 'arch_cmpxchg'
(__typeof__(*(ptr))) __cmpxchg((ptr), \
^
/stuff/linux/arch/riscv/include/asm/cmpxchg.h:335:3: note: expanded from macro '__cmpxchg'
BUILD_BUG(); \
^
note: (skipping 3 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
/stuff/linux/include/linux/compiler_types.h:385:2: note: expanded from macro '_compiletime_assert'
__compiletime_assert(condition, msg, prefix, suffix)
^
/stuff/linux/include/linux/compiler_types.h:378:4: note: expanded from macro '__compiletime_assert'
prefix ## suffix(); \
^
<scratch space>:69:1: note: expanded from here
__compiletime_assert_335
^
/stuff/linux/drivers/platform/surface/aggregator/controller.c:61:25: error: call to __compiletime_assert_335 declared with 'error' attribute: BUILD_BUG failed
/stuff/linux/include/linux/atomic/atomic-instrumented.h:1916:2: note: expanded from macro 'cmpxchg'
arch_cmpxchg(__ai_ptr, __VA_ARGS__); \
^
/stuff/linux/arch/riscv/include/asm/cmpxchg.h:344:23: note: expanded from macro 'arch_cmpxchg'
(__typeof__(*(ptr))) __cmpxchg((ptr), \
^
/stuff/linux/arch/riscv/include/asm/cmpxchg.h:335:3: note: expanded from macro '__cmpxchg'
BUILD_BUG(); \
^
note: (skipping 3 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
/stuff/linux/include/linux/compiler_types.h:385:2: note: expanded from macro '_compiletime_assert'
__compiletime_assert(condition, msg, prefix, suffix)
^
/stuff/linux/include/linux/compiler_types.h:378:4: note: expanded from macro '__compiletime_assert'
prefix ## suffix(); \
^
<scratch space>:69:1: note: expanded from here
__compiletime_assert_335
^
9 errors generated.
On Mon, Mar 06, 2023 at 09:51:09PM +0000, Conor Dooley wrote:
> Hey Sunil,
>
> On Fri, Mar 03, 2023 at 07:06:27PM +0530, Sunil V L wrote:
> > This patch series enables the basic ACPI infrastructure for RISC-V.
> > Supporting external interrupt controllers is in progress and hence it is
> > tested using poll based HVC SBI console and RAM disk.
> >
> > The first patch in this series is one of the patch from Jisheng's
> > series [1] which is not merged yet. This patch is required to support
> > ACPI since efi_init() which gets called before sbi_init() can enable
> > static branches and hits a panic.
> >
> > Patch 2 and 3 are ACPICA patches which are not merged into acpica yet
> > but a PR is raised already.
> >
> > Below are two ECRs approved by ASWG.
> > RINTC - https://drive.google.com/file/d/1R6k4MshhN3WTT-hwqAquu5nX6xSEqK2l/view
> > RHCT - https://drive.google.com/file/d/1nP3nFiH4jkPMp6COOxP6123DCZKR-tia/view
> >
> > The series depends on Anup's IPI improvement series [2].
> >
> > [1] https://lore.kernel.org/all/[email protected]/
> > [2] https://lore.kernel.org/lkml/[email protected]/T/
>
> Building a clang-15 allmodconfig (I didn't try gcc) with this series, and
> Anup's IPI bits, results in a broken build, due to failings in cmpxchg:
>
> /stuff/linux/drivers/platform/surface/aggregator/controller.c:61:25: error: call to __compiletime_assert_335 declared with 'error' attribute: BUILD_BUG failed
> while (unlikely((ret = cmpxchg(&c->value, old, new)) != old)) {
> ^
Hi Conor,
I am able to build without any of these issues using clang-15. I am
wondering whether the base is proper. I had rebased on top of the master
and couple of patches from IPI series were already merged in the master.
Do you mind verifying with my branch
https://github.com/vlsunil/linux/commits/acpi_b1_us_review_ipi17_V3?
Or if you could provide me your branch details, I can look further.
Thanks!
Sunil
On 7 March 2023 05:06:16 GMT, Sunil V L <[email protected]> wrote:
>On Mon, Mar 06, 2023 at 09:51:09PM +0000, Conor Dooley wrote:
>> Hey Sunil,
>>
>> On Fri, Mar 03, 2023 at 07:06:27PM +0530, Sunil V L wrote:
>> > This patch series enables the basic ACPI infrastructure for RISC-V.
>> > Supporting external interrupt controllers is in progress and hence it is
>> > tested using poll based HVC SBI console and RAM disk.
>> >
>> > The first patch in this series is one of the patch from Jisheng's
>> > series [1] which is not merged yet. This patch is required to support
>> > ACPI since efi_init() which gets called before sbi_init() can enable
>> > static branches and hits a panic.
>> >
>> > Patch 2 and 3 are ACPICA patches which are not merged into acpica yet
>> > but a PR is raised already.
>> >
>> > Below are two ECRs approved by ASWG.
>> > RINTC - https://drive.google.com/file/d/1R6k4MshhN3WTT-hwqAquu5nX6xSEqK2l/view
>> > RHCT - https://drive.google.com/file/d/1nP3nFiH4jkPMp6COOxP6123DCZKR-tia/view
>> >
>> > The series depends on Anup's IPI improvement series [2].
>> >
>> > [1] https://lore.kernel.org/all/[email protected]/
>> > [2] https://lore.kernel.org/lkml/[email protected]/T/
>>
>> Building a clang-15 allmodconfig (I didn't try gcc) with this series, and
>> Anup's IPI bits, results in a broken build, due to failings in cmpxchg:
>>
>> /stuff/linux/drivers/platform/surface/aggregator/controller.c:61:25: error: call to __compiletime_assert_335 declared with 'error' attribute: BUILD_BUG failed
>> while (unlikely((ret = cmpxchg(&c->value, old, new)) != old)) {
>> ^
>Hi Conor,
>
>I am able to build without any of these issues using clang-15. I am
>wondering whether the base is proper. I had rebased on top of the master
>and couple of patches from IPI series were already merged in the master.
>
>Do you mind verifying with my branch
>https://github.com/vlsunil/linux/commits/acpi_b1_us_review_ipi17_V3?
I can check that later I suppose.
>
>Or if you could provide me your branch details, I can look further.
6.3-rc1, with both series applied, sans Anups applied patches.
On Tue, Mar 07, 2023 at 06:13:22AM +0000, Conor Dooley wrote:
>
>
> On 7 March 2023 05:06:16 GMT, Sunil V L <[email protected]> wrote:
> >On Mon, Mar 06, 2023 at 09:51:09PM +0000, Conor Dooley wrote:
> >> Hey Sunil,
> >>
> >> On Fri, Mar 03, 2023 at 07:06:27PM +0530, Sunil V L wrote:
> >> > This patch series enables the basic ACPI infrastructure for RISC-V.
> >> > Supporting external interrupt controllers is in progress and hence it is
> >> > tested using poll based HVC SBI console and RAM disk.
> >> >
> >> > The first patch in this series is one of the patch from Jisheng's
> >> > series [1] which is not merged yet. This patch is required to support
> >> > ACPI since efi_init() which gets called before sbi_init() can enable
> >> > static branches and hits a panic.
> >> >
> >> > Patch 2 and 3 are ACPICA patches which are not merged into acpica yet
> >> > but a PR is raised already.
> >> >
> >> > Below are two ECRs approved by ASWG.
> >> > RINTC - https://drive.google.com/file/d/1R6k4MshhN3WTT-hwqAquu5nX6xSEqK2l/view
> >> > RHCT - https://drive.google.com/file/d/1nP3nFiH4jkPMp6COOxP6123DCZKR-tia/view
> >> >
> >> > The series depends on Anup's IPI improvement series [2].
> >> >
> >> > [1] https://lore.kernel.org/all/[email protected]/
> >> > [2] https://lore.kernel.org/lkml/[email protected]/T/
> >>
> >> Building a clang-15 allmodconfig (I didn't try gcc) with this series, and
> >> Anup's IPI bits, results in a broken build, due to failings in cmpxchg:
> >>
> >> /stuff/linux/drivers/platform/surface/aggregator/controller.c:61:25: error: call to __compiletime_assert_335 declared with 'error' attribute: BUILD_BUG failed
> >> while (unlikely((ret = cmpxchg(&c->value, old, new)) != old)) {
> >> ^
> > I am able to build without any of these issues using clang-15. I am
> > wondering whether the base is proper. I had rebased on top of the master
> > and couple of patches from IPI series were already merged in the master.
> >
> > Do you mind verifying with my branch
> > https://github.com/vlsunil/linux/commits/acpi_b1_us_review_ipi17_V3?
>
> I can check that later I suppose.
That's broken too.
> > Or if you could provide me your branch details, I can look further.
>
> 6.3-rc1, with both series applied, sans Anups applied patches.
I've pushed my stuff here, but unlikely that it makes any odds since
your branch experiences the same build issue.
https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/ borked-acpi-surface
My build commands are wrapped in a script, but it's an LLVM=1
allmodconfig run w/ clang-15(.0.7) etc.
Chees,
Conor.
On Tue, Mar 07, 2023 at 06:44:35PM +0000, Conor Dooley wrote:
> On Tue, Mar 07, 2023 at 06:13:22AM +0000, Conor Dooley wrote:
> >
> >
> > On 7 March 2023 05:06:16 GMT, Sunil V L <[email protected]> wrote:
> > >On Mon, Mar 06, 2023 at 09:51:09PM +0000, Conor Dooley wrote:
> > >> Hey Sunil,
> > >>
> > >> On Fri, Mar 03, 2023 at 07:06:27PM +0530, Sunil V L wrote:
> > >> > This patch series enables the basic ACPI infrastructure for RISC-V.
> > >> > Supporting external interrupt controllers is in progress and hence it is
> > >> > tested using poll based HVC SBI console and RAM disk.
> > >> >
> > >> > The first patch in this series is one of the patch from Jisheng's
> > >> > series [1] which is not merged yet. This patch is required to support
> > >> > ACPI since efi_init() which gets called before sbi_init() can enable
> > >> > static branches and hits a panic.
> > >> >
> > >> > Patch 2 and 3 are ACPICA patches which are not merged into acpica yet
> > >> > but a PR is raised already.
> > >> >
> > >> > Below are two ECRs approved by ASWG.
> > >> > RINTC - https://drive.google.com/file/d/1R6k4MshhN3WTT-hwqAquu5nX6xSEqK2l/view
> > >> > RHCT - https://drive.google.com/file/d/1nP3nFiH4jkPMp6COOxP6123DCZKR-tia/view
> > >> >
> > >> > The series depends on Anup's IPI improvement series [2].
> > >> >
> > >> > [1] https://lore.kernel.org/all/[email protected]/
> > >> > [2] https://lore.kernel.org/lkml/[email protected]/T/
> > >>
> > >> Building a clang-15 allmodconfig (I didn't try gcc) with this series, and
> > >> Anup's IPI bits, results in a broken build, due to failings in cmpxchg:
> > >>
> > >> /stuff/linux/drivers/platform/surface/aggregator/controller.c:61:25: error: call to __compiletime_assert_335 declared with 'error' attribute: BUILD_BUG failed
> > >> while (unlikely((ret = cmpxchg(&c->value, old, new)) != old)) {
> > >> ^
>
> > > I am able to build without any of these issues using clang-15. I am
> > > wondering whether the base is proper. I had rebased on top of the master
> > > and couple of patches from IPI series were already merged in the master.
> > >
> > > Do you mind verifying with my branch
> > > https://github.com/vlsunil/linux/commits/acpi_b1_us_review_ipi17_V3?
> >
> > I can check that later I suppose.
>
> That's broken too.
>
> > > Or if you could provide me your branch details, I can look further.
> >
> > 6.3-rc1, with both series applied, sans Anups applied patches.
>
> I've pushed my stuff here, but unlikely that it makes any odds since
> your branch experiences the same build issue.
> https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/ borked-acpi-surface
>
> My build commands are wrapped in a script, but it's an LLVM=1
> allmodconfig run w/ clang-15(.0.7) etc.
>
Ahh allmodconfig. Thank you very much!. I can reproduce the failure. Let
me look further and fix in next revision.
Thanks!
Sunil
On Mon, Mar 06, 2023 at 09:17:34PM +0000, Conor Dooley wrote:
> On Fri, Mar 03, 2023 at 07:06:45PM +0530, Sunil V L wrote:
> > Initialize the ACPI core for RISC-V during boot.
> >
> > ACPI tables and interpreter are initialized based on
> > the information passed from the firmware and the value of
> > the kernel parameter 'acpi'.
> >
> > With ACPI support added for RISC-V, the kernel parameter 'acpi'
> > is also supported on RISC-V. Hence, update the documentation.
> >
> > Signed-off-by: Sunil V L <[email protected]>
> > Acked-by: Rafael J. Wysocki <[email protected]>
> > Reviewed-by: Andrew Jones <[email protected]>
> > ---
>
> > +static int __init acpi_fadt_sanity_check(void)
> > +{
> > + struct acpi_table_header *table;
> > + struct acpi_table_fadt *fadt;
> > + acpi_status status;
> > + int ret = 0;
> > +
> > + /*
> > + * FADT is required on riscv; retrieve it to check its presence
> > + * and carry out revision and ACPI HW reduced compliancy tests
> > + */
> > + status = acpi_get_table(ACPI_SIG_FADT, 0, &table);
> > + if (ACPI_FAILURE(status)) {
> > + const char *msg = acpi_format_exception(status);
> > +
> > + pr_err("Failed to get FADT table, %s\n", msg);
> > + return -ENODEV;
> > + }
> > +
> > + fadt = (struct acpi_table_fadt *)table;
> > +
> > + /*
> > + * Revision in table header is the FADT Major revision, and there
> > + * is a minor revision of FADT.
>
> What is the point of this part of the comment? Isn't it obvious from the
> below code that you expect a major and minor revision?
> If feel like you're trying to make a point in it, but the point has been
> lost :/
>
It just highlights that major and minor revision fields are in two
different places. Let me remove this comment since it is part of the
spec anyway.
Thanks,
Sunil
On Mon, Mar 06, 2023 at 09:09:11PM +0000, Conor Dooley wrote:
> On Fri, Mar 03, 2023 at 07:06:44PM +0530, Sunil V L wrote:
> > On ACPI based platforms, timer related information is
> > available in RHCT. Add ACPI based probe support to the
> > timer initialization.
> >
> > Signed-off-by: Sunil V L <[email protected]>
> > Acked-by: Rafael J. Wysocki <[email protected]>
> > Reviewed-by: Andrew Jones <[email protected]>
> > ---
> > arch/riscv/kernel/time.c | 23 +++++++++++++++++------
> > 1 file changed, 17 insertions(+), 6 deletions(-)
> >
> > diff --git a/arch/riscv/kernel/time.c b/arch/riscv/kernel/time.c
> > index babaf3b48ba8..2c29543549c3 100644
> > --- a/arch/riscv/kernel/time.c
> > +++ b/arch/riscv/kernel/time.c
> > @@ -4,6 +4,7 @@
> > * Copyright (C) 2017 SiFive
> > */
> >
> > +#include <linux/acpi.h>
> > #include <linux/of_clk.h>
> > #include <linux/clockchips.h>
> > #include <linux/clocksource.h>
> > @@ -18,17 +19,27 @@ EXPORT_SYMBOL_GPL(riscv_timebase);
> > void __init time_init(void)
> > {
> > struct device_node *cpu;
> > + struct acpi_table_rhct *rhct;
> > + acpi_status status;
> > u32 prop;
> >
> > - cpu = of_find_node_by_path("/cpus");
> > - if (!cpu || of_property_read_u32(cpu, "timebase-frequency", &prop))
> > - panic(KERN_WARNING "RISC-V system with no 'timebase-frequency' in DTS\n");
> > - of_node_put(cpu);
> > - riscv_timebase = prop;
> > + if (acpi_disabled) {
> > + cpu = of_find_node_by_path("/cpus");
> > + if (!cpu || of_property_read_u32(cpu, "timebase-frequency", &prop))
> > + panic("RISC-V system with no 'timebase-frequency' in DTS\n");
>
> I appreciate that it was like this before, but a newline here (and in
> the corresponding spot below) would be nice.
Sure!. Will update in next revision.
Thanks,
Sunil
On Wed, Mar 08, 2023 at 03:12:18PM +0530, Sunil V L wrote:
> On Mon, Mar 06, 2023 at 09:17:34PM +0000, Conor Dooley wrote:
> > On Fri, Mar 03, 2023 at 07:06:45PM +0530, Sunil V L wrote:
> > > Initialize the ACPI core for RISC-V during boot.
> > >
> > > ACPI tables and interpreter are initialized based on
> > > the information passed from the firmware and the value of
> > > the kernel parameter 'acpi'.
> > >
> > > With ACPI support added for RISC-V, the kernel parameter 'acpi'
> > > is also supported on RISC-V. Hence, update the documentation.
> > >
> > > Signed-off-by: Sunil V L <[email protected]>
> > > Acked-by: Rafael J. Wysocki <[email protected]>
> > > Reviewed-by: Andrew Jones <[email protected]>
> > > ---
> >
> > > +static int __init acpi_fadt_sanity_check(void)
> > > +{
> > > + struct acpi_table_header *table;
> > > + struct acpi_table_fadt *fadt;
> > > + acpi_status status;
> > > + int ret = 0;
> > > +
> > > + /*
> > > + * FADT is required on riscv; retrieve it to check its presence
> > > + * and carry out revision and ACPI HW reduced compliancy tests
> > > + */
> > > + status = acpi_get_table(ACPI_SIG_FADT, 0, &table);
> > > + if (ACPI_FAILURE(status)) {
> > > + const char *msg = acpi_format_exception(status);
> > > +
> > > + pr_err("Failed to get FADT table, %s\n", msg);
> > > + return -ENODEV;
> > > + }
> > > +
> > > + fadt = (struct acpi_table_fadt *)table;
> > > +
> > > + /*
> > > + * Revision in table header is the FADT Major revision, and there
> > > + * is a minor revision of FADT.
> >
> > What is the point of this part of the comment? Isn't it obvious from the
> > below code that you expect a major and minor revision?
> > If feel like you're trying to make a point in it, but the point has been
> > lost :/
> >
> It just highlights that major and minor revision fields are in two
> different places.
I thought that that was what you meant, but only because the code does
it. The comment doesn't actually say so!
Instead of deleting it, something like the following?
/*
* The revision in the table header is the FADT's Major revision. The
* FADT also has a minor revision, which is stored in the FADT itself.
* <snip>
On Wed, Mar 8, 2023 at 9:08 AM Sunil V L <[email protected]> wrote:
>
> On Tue, Mar 07, 2023 at 06:44:35PM +0000, Conor Dooley wrote:
> > On Tue, Mar 07, 2023 at 06:13:22AM +0000, Conor Dooley wrote:
> > >
> > >
> > > On 7 March 2023 05:06:16 GMT, Sunil V L <[email protected]> wrote:
> > > >On Mon, Mar 06, 2023 at 09:51:09PM +0000, Conor Dooley wrote:
> > > >> Hey Sunil,
> > > >>
> > > >> On Fri, Mar 03, 2023 at 07:06:27PM +0530, Sunil V L wrote:
> > > >> > This patch series enables the basic ACPI infrastructure for RISC-V.
> > > >> > Supporting external interrupt controllers is in progress and hence it is
> > > >> > tested using poll based HVC SBI console and RAM disk.
> > > >> >
> > > >> > The first patch in this series is one of the patch from Jisheng's
> > > >> > series [1] which is not merged yet. This patch is required to support
> > > >> > ACPI since efi_init() which gets called before sbi_init() can enable
> > > >> > static branches and hits a panic.
> > > >> >
> > > >> > Patch 2 and 3 are ACPICA patches which are not merged into acpica yet
> > > >> > but a PR is raised already.
> > > >> >
> > > >> > Below are two ECRs approved by ASWG.
> > > >> > RINTC - https://drive.google.com/file/d/1R6k4MshhN3WTT-hwqAquu5nX6xSEqK2l/view
> > > >> > RHCT - https://drive.google.com/file/d/1nP3nFiH4jkPMp6COOxP6123DCZKR-tia/view
> > > >> >
> > > >> > The series depends on Anup's IPI improvement series [2].
> > > >> >
> > > >> > [1] https://lore.kernel.org/all/[email protected]/
> > > >> > [2] https://lore.kernel.org/lkml/[email protected]/T/
> > > >>
> > > >> Building a clang-15 allmodconfig (I didn't try gcc) with this series, and
> > > >> Anup's IPI bits, results in a broken build, due to failings in cmpxchg:
> > > >>
> > > >> /stuff/linux/drivers/platform/surface/aggregator/controller.c:61:25: error: call to __compiletime_assert_335 declared with 'error' attribute: BUILD_BUG failed
> > > >> while (unlikely((ret = cmpxchg(&c->value, old, new)) != old)) {
> > > >> ^
> >
> > > > I am able to build without any of these issues using clang-15. I am
> > > > wondering whether the base is proper. I had rebased on top of the master
> > > > and couple of patches from IPI series were already merged in the master.
> > > >
> > > > Do you mind verifying with my branch
> > > > https://github.com/vlsunil/linux/commits/acpi_b1_us_review_ipi17_V3?
> > >
> > > I can check that later I suppose.
> >
> > That's broken too.
> >
> > > > Or if you could provide me your branch details, I can look further.
> > >
> > > 6.3-rc1, with both series applied, sans Anups applied patches.
> >
> > I've pushed my stuff here, but unlikely that it makes any odds since
> > your branch experiences the same build issue.
> > https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/ borked-acpi-surface
> >
> > My build commands are wrapped in a script, but it's an LLVM=1
> > allmodconfig run w/ clang-15(.0.7) etc.
> >
> Ahh allmodconfig. Thank you very much!. I can reproduce the failure. Let
> me look further and fix in next revision.
>
> Thanks!
> Sunil
Hi Sunil
One question regarding PMU in ACPI flow.
We use DT to decode the supported HPM counters/events for the
different platforms now.
How do we enable PMU (drivers/perf/riscv_pmu_sbi.c) when using ACPI method?
Note, this might be in separate patch series.
Regards
Ley Foon
On Tue, Apr 04, 2023 at 02:35:19PM +0800, Ley Foon Tan wrote:
> On Wed, Mar 8, 2023 at 9:08 AM Sunil V L <[email protected]> wrote:
> >
> > On Tue, Mar 07, 2023 at 06:44:35PM +0000, Conor Dooley wrote:
> > > On Tue, Mar 07, 2023 at 06:13:22AM +0000, Conor Dooley wrote:
> > > >
> > > >
> > > > On 7 March 2023 05:06:16 GMT, Sunil V L <[email protected]> wrote:
> > > > >On Mon, Mar 06, 2023 at 09:51:09PM +0000, Conor Dooley wrote:
> > > > >> Hey Sunil,
> > > > >>
> > > > >> On Fri, Mar 03, 2023 at 07:06:27PM +0530, Sunil V L wrote:
> > > > >> > This patch series enables the basic ACPI infrastructure for RISC-V.
> > > > >> > Supporting external interrupt controllers is in progress and hence it is
> > > > >> > tested using poll based HVC SBI console and RAM disk.
> > > > >> >
> > > > >> > The first patch in this series is one of the patch from Jisheng's
> > > > >> > series [1] which is not merged yet. This patch is required to support
> > > > >> > ACPI since efi_init() which gets called before sbi_init() can enable
> > > > >> > static branches and hits a panic.
> > > > >> >
> > > > >> > Patch 2 and 3 are ACPICA patches which are not merged into acpica yet
> > > > >> > but a PR is raised already.
> > > > >> >
> > > > >> > Below are two ECRs approved by ASWG.
> > > > >> > RINTC - https://drive.google.com/file/d/1R6k4MshhN3WTT-hwqAquu5nX6xSEqK2l/view
> > > > >> > RHCT - https://drive.google.com/file/d/1nP3nFiH4jkPMp6COOxP6123DCZKR-tia/view
> > > > >> >
> > > > >> > The series depends on Anup's IPI improvement series [2].
> > > > >> >
> > > > >> > [1] https://lore.kernel.org/all/[email protected]/
> > > > >> > [2] https://lore.kernel.org/lkml/[email protected]/T/
> > > > >>
> > > > >> Building a clang-15 allmodconfig (I didn't try gcc) with this series, and
> > > > >> Anup's IPI bits, results in a broken build, due to failings in cmpxchg:
> > > > >>
> > > > >> /stuff/linux/drivers/platform/surface/aggregator/controller.c:61:25: error: call to __compiletime_assert_335 declared with 'error' attribute: BUILD_BUG failed
> > > > >> while (unlikely((ret = cmpxchg(&c->value, old, new)) != old)) {
> > > > >> ^
> > >
> > > > > I am able to build without any of these issues using clang-15. I am
> > > > > wondering whether the base is proper. I had rebased on top of the master
> > > > > and couple of patches from IPI series were already merged in the master.
> > > > >
> > > > > Do you mind verifying with my branch
> > > > > https://github.com/vlsunil/linux/commits/acpi_b1_us_review_ipi17_V3?
> > > >
> > > > I can check that later I suppose.
> > >
> > > That's broken too.
> > >
> > > > > Or if you could provide me your branch details, I can look further.
> > > >
> > > > 6.3-rc1, with both series applied, sans Anups applied patches.
> > >
> > > I've pushed my stuff here, but unlikely that it makes any odds since
> > > your branch experiences the same build issue.
> > > https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/ borked-acpi-surface
> > >
> > > My build commands are wrapped in a script, but it's an LLVM=1
> > > allmodconfig run w/ clang-15(.0.7) etc.
> > >
> > Ahh allmodconfig. Thank you very much!. I can reproduce the failure. Let
> > me look further and fix in next revision.
> >
> > Thanks!
> > Sunil
>
> Hi Sunil
>
> One question regarding PMU in ACPI flow.
>
> We use DT to decode the supported HPM counters/events for the
> different platforms now.
> How do we enable PMU (drivers/perf/riscv_pmu_sbi.c) when using ACPI method?
> Note, this might be in separate patch series.
>
Hi Lay Foon,
This driver uses SBI calls and hence should work in case of ACPI also.
There is one minor change required in this driver for overflow
interrupt. I have a patch for that in future series.
Thanks,
Sunil
On Tue, Apr 4, 2023 at 12:24 PM Sunil V L <[email protected]> wrote:
>
> On Tue, Apr 04, 2023 at 02:35:19PM +0800, Ley Foon Tan wrote:
> > On Wed, Mar 8, 2023 at 9:08 AM Sunil V L <[email protected]> wrote:
> > >
> > > On Tue, Mar 07, 2023 at 06:44:35PM +0000, Conor Dooley wrote:
> > > > On Tue, Mar 07, 2023 at 06:13:22AM +0000, Conor Dooley wrote:
> > > > >
> > > > >
> > > > > On 7 March 2023 05:06:16 GMT, Sunil V L <[email protected]> wrote:
> > > > > >On Mon, Mar 06, 2023 at 09:51:09PM +0000, Conor Dooley wrote:
> > > > > >> Hey Sunil,
> > > > > >>
> > > > > >> On Fri, Mar 03, 2023 at 07:06:27PM +0530, Sunil V L wrote:
> > > > > >> > This patch series enables the basic ACPI infrastructure for RISC-V.
> > > > > >> > Supporting external interrupt controllers is in progress and hence it is
> > > > > >> > tested using poll based HVC SBI console and RAM disk.
> > > > > >> >
> > > > > >> > The first patch in this series is one of the patch from Jisheng's
> > > > > >> > series [1] which is not merged yet. This patch is required to support
> > > > > >> > ACPI since efi_init() which gets called before sbi_init() can enable
> > > > > >> > static branches and hits a panic.
> > > > > >> >
> > > > > >> > Patch 2 and 3 are ACPICA patches which are not merged into acpica yet
> > > > > >> > but a PR is raised already.
> > > > > >> >
> > > > > >> > Below are two ECRs approved by ASWG.
> > > > > >> > RINTC - https://drive.google.com/file/d/1R6k4MshhN3WTT-hwqAquu5nX6xSEqK2l/view
> > > > > >> > RHCT - https://drive.google.com/file/d/1nP3nFiH4jkPMp6COOxP6123DCZKR-tia/view
> > > > > >> >
> > > > > >> > The series depends on Anup's IPI improvement series [2].
> > > > > >> >
> > > > > >> > [1] https://lore.kernel.org/all/[email protected]/
> > > > > >> > [2] https://lore.kernel.org/lkml/[email protected]/T/
> > > > > >>
> > > > > >> Building a clang-15 allmodconfig (I didn't try gcc) with this series, and
> > > > > >> Anup's IPI bits, results in a broken build, due to failings in cmpxchg:
> > > > > >>
> > > > > >> /stuff/linux/drivers/platform/surface/aggregator/controller.c:61:25: error: call to __compiletime_assert_335 declared with 'error' attribute: BUILD_BUG failed
> > > > > >> while (unlikely((ret = cmpxchg(&c->value, old, new)) != old)) {
> > > > > >> ^
> > > >
> > > > > > I am able to build without any of these issues using clang-15. I am
> > > > > > wondering whether the base is proper. I had rebased on top of the master
> > > > > > and couple of patches from IPI series were already merged in the master.
> > > > > >
> > > > > > Do you mind verifying with my branch
> > > > > > https://github.com/vlsunil/linux/commits/acpi_b1_us_review_ipi17_V3?
> > > > >
> > > > > I can check that later I suppose.
> > > >
> > > > That's broken too.
> > > >
> > > > > > Or if you could provide me your branch details, I can look further.
> > > > >
> > > > > 6.3-rc1, with both series applied, sans Anups applied patches.
> > > >
> > > > I've pushed my stuff here, but unlikely that it makes any odds since
> > > > your branch experiences the same build issue.
> > > > https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/ borked-acpi-surface
> > > >
> > > > My build commands are wrapped in a script, but it's an LLVM=1
> > > > allmodconfig run w/ clang-15(.0.7) etc.
> > > >
> > > Ahh allmodconfig. Thank you very much!. I can reproduce the failure. Let
> > > me look further and fix in next revision.
> > >
> > > Thanks!
> > > Sunil
> >
> > Hi Sunil
> >
> > One question regarding PMU in ACPI flow.
> >
> > We use DT to decode the supported HPM counters/events for the
> > different platforms now.
> > How do we enable PMU (drivers/perf/riscv_pmu_sbi.c) when using ACPI method?
> > Note, this might be in separate patch series.
> >
> Hi Lay Foon,
>
> This driver uses SBI calls and hence should work in case of ACPI also.
>
> There is one minor change required in this driver for overflow
> interrupt. I have a patch for that in future series.
Just to add further clarification: OpenSBI will continue to use the
device tree so that
the firmware will have access to all the PMU details.
>
> Thanks,
> Sunil
On Thu, Apr 6, 2023 at 10:45 AM Atish Kumar Patra <[email protected]> wrote:
>
> > >
> > > Hi Sunil
> > >
> > > One question regarding PMU in ACPI flow.
> > >
> > > We use DT to decode the supported HPM counters/events for the
> > > different platforms now.
> > > How do we enable PMU (drivers/perf/riscv_pmu_sbi.c) when using ACPI method?
> > > Note, this might be in separate patch series.
> > >
> > Hi Lay Foon,
> >
> > This driver uses SBI calls and hence should work in case of ACPI also.
> >
> > There is one minor change required in this driver for overflow
> > interrupt. I have a patch for that in future series.
>
> Just to add further clarification: OpenSBI will continue to use the
> device tree so that
> the firmware will have access to all the PMU details.
>
Sorry for the late reply, missed out on this email in my kernel.org mailbox.
Do you mean OpenSBI still using the device tree, but EDK II and Linux
using the ACPI table? Normally Linux shouldn't mix between ACPI and
device tree.
Regards
Ley Foon
On Wed, Apr 19, 2023 at 1:38 PM Ley Foon Tan <[email protected]> wrote:
>
> On Thu, Apr 6, 2023 at 10:45 AM Atish Kumar Patra <[email protected]> wrote:
> >
>
> > > >
> > > > Hi Sunil
> > > >
> > > > One question regarding PMU in ACPI flow.
> > > >
> > > > We use DT to decode the supported HPM counters/events for the
> > > > different platforms now.
> > > > How do we enable PMU (drivers/perf/riscv_pmu_sbi.c) when using ACPI method?
> > > > Note, this might be in separate patch series.
> > > >
> > > Hi Lay Foon,
> > >
> > > This driver uses SBI calls and hence should work in case of ACPI also.
> > >
> > > There is one minor change required in this driver for overflow
> > > interrupt. I have a patch for that in future series.
> >
> > Just to add further clarification: OpenSBI will continue to use the
> > device tree so that
> > the firmware will have access to all the PMU details.
> >
> Sorry for the late reply, missed out on this email in my kernel.org mailbox.
>
> Do you mean OpenSBI still using the device tree, but EDK II and Linux
> using the ACPI table? Normally Linux shouldn't mix between ACPI and
Yes. For Linux, it will only be ACPI. Otherwise, we have to define all
those bindings in ACPI as well.
In the future, we will have supervisor counter delegation ISA
extension(in progress) that allows the kernel to directly program
the hpmevents & modify counters without needing SBI PMU extension.
> device tree.
>
> Regards
> Ley Foon
>
> _______________________________________________
> linux-riscv mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-riscv
--
Regards,
Atish