* [kvm-unit-tests PATCH v5 01/29] lib: Move acpi header and implementation to lib
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
@ 2023-04-28 12:03 ` Nikos Nikoleris
2023-05-01 12:41 ` Shaoqin Huang
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 02/29] x86: Move x86_64-specific EFI CFLAGS to x86_64 Makefile Nikos Nikoleris
` (29 subsequent siblings)
30 siblings, 1 reply; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-28 12:03 UTC (permalink / raw)
To: kvm, kvmarm, andrew.jones; +Cc: pbonzini, alexandru.elisei, ricarkol
Move acpi.h to lib to make it available for other architectures.
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
---
x86/Makefile.common | 2 +-
lib/x86/asm/setup.h | 2 +-
lib/{x86 => }/acpi.h | 4 ++--
lib/{x86 => }/acpi.c | 0
x86/s3.c | 2 +-
x86/vmexit.c | 2 +-
6 files changed, 6 insertions(+), 6 deletions(-)
rename lib/{x86 => }/acpi.h (99%)
rename lib/{x86 => }/acpi.c (100%)
diff --git a/x86/Makefile.common b/x86/Makefile.common
index 365e199f..9f2bc93f 100644
--- a/x86/Makefile.common
+++ b/x86/Makefile.common
@@ -2,6 +2,7 @@
all: directories test_cases
+cflatobjs += lib/acpi.o
cflatobjs += lib/pci.o
cflatobjs += lib/pci-edu.o
cflatobjs += lib/alloc.o
@@ -18,7 +19,6 @@ cflatobjs += lib/x86/apic.o
cflatobjs += lib/x86/atomic.o
cflatobjs += lib/x86/desc.o
cflatobjs += lib/x86/isr.o
-cflatobjs += lib/x86/acpi.o
cflatobjs += lib/x86/stack.o
cflatobjs += lib/x86/fault_test.o
cflatobjs += lib/x86/delay.o
diff --git a/lib/x86/asm/setup.h b/lib/x86/asm/setup.h
index 1f384274..458eac85 100644
--- a/lib/x86/asm/setup.h
+++ b/lib/x86/asm/setup.h
@@ -4,7 +4,7 @@
unsigned long setup_tss(u8 *stacktop);
#ifdef CONFIG_EFI
-#include "x86/acpi.h"
+#include "acpi.h"
#include "x86/apic.h"
#include "x86/processor.h"
#include "x86/smp.h"
diff --git a/lib/x86/acpi.h b/lib/acpi.h
similarity index 99%
rename from lib/x86/acpi.h
rename to lib/acpi.h
index 67ba3899..1e89840c 100644
--- a/lib/x86/acpi.h
+++ b/lib/acpi.h
@@ -1,5 +1,5 @@
-#ifndef _X86_ACPI_H_
-#define _X86_ACPI_H_
+#ifndef _ACPI_H_
+#define _ACPI_H_
#include "libcflat.h"
diff --git a/lib/x86/acpi.c b/lib/acpi.c
similarity index 100%
rename from lib/x86/acpi.c
rename to lib/acpi.c
diff --git a/x86/s3.c b/x86/s3.c
index 6e41d0c4..378d37ae 100644
--- a/x86/s3.c
+++ b/x86/s3.c
@@ -1,5 +1,5 @@
#include "libcflat.h"
-#include "x86/acpi.h"
+#include "acpi.h"
#include "asm/io.h"
static u32* find_resume_vector_addr(void)
diff --git a/x86/vmexit.c b/x86/vmexit.c
index 2e8866e1..9260accc 100644
--- a/x86/vmexit.c
+++ b/x86/vmexit.c
@@ -1,9 +1,9 @@
#include "libcflat.h"
+#include "acpi.h"
#include "smp.h"
#include "pci.h"
#include "x86/vm.h"
#include "x86/desc.h"
-#include "x86/acpi.h"
#include "x86/apic.h"
#include "x86/isr.h"
--
2.25.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* Re: [kvm-unit-tests PATCH v5 01/29] lib: Move acpi header and implementation to lib
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 01/29] lib: Move acpi header and implementation to lib Nikos Nikoleris
@ 2023-05-01 12:41 ` Shaoqin Huang
0 siblings, 0 replies; 52+ messages in thread
From: Shaoqin Huang @ 2023-05-01 12:41 UTC (permalink / raw)
To: Nikos Nikoleris, kvm, kvmarm, andrew.jones
Cc: pbonzini, alexandru.elisei, ricarkol
On 4/28/23 20:03, Nikos Nikoleris wrote:
> Move acpi.h to lib to make it available for other architectures.
>
> Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Shaoqin Huang <shahuang@redhat.com>
> ---
> x86/Makefile.common | 2 +-
> lib/x86/asm/setup.h | 2 +-
> lib/{x86 => }/acpi.h | 4 ++--
> lib/{x86 => }/acpi.c | 0
> x86/s3.c | 2 +-
> x86/vmexit.c | 2 +-
> 6 files changed, 6 insertions(+), 6 deletions(-)
> rename lib/{x86 => }/acpi.h (99%)
> rename lib/{x86 => }/acpi.c (100%)
>
> diff --git a/x86/Makefile.common b/x86/Makefile.common
> index 365e199f..9f2bc93f 100644
> --- a/x86/Makefile.common
> +++ b/x86/Makefile.common
> @@ -2,6 +2,7 @@
>
> all: directories test_cases
>
> +cflatobjs += lib/acpi.o
> cflatobjs += lib/pci.o
> cflatobjs += lib/pci-edu.o
> cflatobjs += lib/alloc.o
> @@ -18,7 +19,6 @@ cflatobjs += lib/x86/apic.o
> cflatobjs += lib/x86/atomic.o
> cflatobjs += lib/x86/desc.o
> cflatobjs += lib/x86/isr.o
> -cflatobjs += lib/x86/acpi.o
> cflatobjs += lib/x86/stack.o
> cflatobjs += lib/x86/fault_test.o
> cflatobjs += lib/x86/delay.o
> diff --git a/lib/x86/asm/setup.h b/lib/x86/asm/setup.h
> index 1f384274..458eac85 100644
> --- a/lib/x86/asm/setup.h
> +++ b/lib/x86/asm/setup.h
> @@ -4,7 +4,7 @@
> unsigned long setup_tss(u8 *stacktop);
>
> #ifdef CONFIG_EFI
> -#include "x86/acpi.h"
> +#include "acpi.h"
> #include "x86/apic.h"
> #include "x86/processor.h"
> #include "x86/smp.h"
> diff --git a/lib/x86/acpi.h b/lib/acpi.h
> similarity index 99%
> rename from lib/x86/acpi.h
> rename to lib/acpi.h
> index 67ba3899..1e89840c 100644
> --- a/lib/x86/acpi.h
> +++ b/lib/acpi.h
> @@ -1,5 +1,5 @@
> -#ifndef _X86_ACPI_H_
> -#define _X86_ACPI_H_
> +#ifndef _ACPI_H_
> +#define _ACPI_H_
>
> #include "libcflat.h"
>
> diff --git a/lib/x86/acpi.c b/lib/acpi.c
> similarity index 100%
> rename from lib/x86/acpi.c
> rename to lib/acpi.c
> diff --git a/x86/s3.c b/x86/s3.c
> index 6e41d0c4..378d37ae 100644
> --- a/x86/s3.c
> +++ b/x86/s3.c
> @@ -1,5 +1,5 @@
> #include "libcflat.h"
> -#include "x86/acpi.h"
> +#include "acpi.h"
> #include "asm/io.h"
>
> static u32* find_resume_vector_addr(void)
> diff --git a/x86/vmexit.c b/x86/vmexit.c
> index 2e8866e1..9260accc 100644
> --- a/x86/vmexit.c
> +++ b/x86/vmexit.c
> @@ -1,9 +1,9 @@
> #include "libcflat.h"
> +#include "acpi.h"
> #include "smp.h"
> #include "pci.h"
> #include "x86/vm.h"
> #include "x86/desc.h"
> -#include "x86/acpi.h"
> #include "x86/apic.h"
> #include "x86/isr.h"
>
--
Shaoqin
^ permalink raw reply [flat|nested] 52+ messages in thread
* [kvm-unit-tests PATCH v5 02/29] x86: Move x86_64-specific EFI CFLAGS to x86_64 Makefile
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 01/29] lib: Move acpi header and implementation to lib Nikos Nikoleris
@ 2023-04-28 12:03 ` Nikos Nikoleris
2023-05-01 12:41 ` Shaoqin Huang
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 03/29] lib: Apply Lindent to acpi.{c,h} Nikos Nikoleris
` (28 subsequent siblings)
30 siblings, 1 reply; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-28 12:03 UTC (permalink / raw)
To: kvm, kvmarm, andrew.jones; +Cc: pbonzini, alexandru.elisei, ricarkol
Compiler flag -macculate-outgoing-args is only needed by the x86_64
ABI. Move it to the relevant Makefile.
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Ricardo Koller <ricarkol@google.com>
---
Makefile | 4 ----
x86/Makefile.x86_64 | 4 ++++
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/Makefile b/Makefile
index 6ed5deac..307bc291 100644
--- a/Makefile
+++ b/Makefile
@@ -40,14 +40,10 @@ OBJDIRS += $(LIBFDT_objdir)
# EFI App
ifeq ($(CONFIG_EFI),y)
-EFI_ARCH = x86_64
EFI_CFLAGS := -DCONFIG_EFI
# The following CFLAGS and LDFLAGS come from:
# - GNU-EFI/Makefile.defaults
# - GNU-EFI/apps/Makefile
-# Function calls must include the number of arguments passed to the functions
-# More details: https://wiki.osdev.org/GNU-EFI
-EFI_CFLAGS += -maccumulate-outgoing-args
# GCC defines wchar to be 32 bits, but EFI expects 16 bits
EFI_CFLAGS += -fshort-wchar
# EFI applications use PIC as they are loaded to dynamic addresses, not a fixed
diff --git a/x86/Makefile.x86_64 b/x86/Makefile.x86_64
index f483dead..2771a6fa 100644
--- a/x86/Makefile.x86_64
+++ b/x86/Makefile.x86_64
@@ -2,6 +2,10 @@ cstart.o = $(TEST_DIR)/cstart64.o
bits = 64
ldarch = elf64-x86-64
ifeq ($(CONFIG_EFI),y)
+# Function calls must include the number of arguments passed to the functions
+# More details: https://wiki.osdev.org/GNU-EFI
+CFLAGS += -maccumulate-outgoing-args
+
exe = efi
bin = so
FORMAT = efi-app-x86_64
--
2.25.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* Re: [kvm-unit-tests PATCH v5 02/29] x86: Move x86_64-specific EFI CFLAGS to x86_64 Makefile
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 02/29] x86: Move x86_64-specific EFI CFLAGS to x86_64 Makefile Nikos Nikoleris
@ 2023-05-01 12:41 ` Shaoqin Huang
0 siblings, 0 replies; 52+ messages in thread
From: Shaoqin Huang @ 2023-05-01 12:41 UTC (permalink / raw)
To: Nikos Nikoleris, kvm, kvmarm, andrew.jones
Cc: pbonzini, alexandru.elisei, ricarkol
On 4/28/23 20:03, Nikos Nikoleris wrote:
> Compiler flag -macculate-outgoing-args is only needed by the x86_64
> ABI. Move it to the relevant Makefile.
>
> Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
> Reviewed-by: Ricardo Koller <ricarkol@google.com>
Reviewed-by: Shaoqin Huang <shahuang@redhat.com>
> ---
> Makefile | 4 ----
> x86/Makefile.x86_64 | 4 ++++
> 2 files changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/Makefile b/Makefile
> index 6ed5deac..307bc291 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -40,14 +40,10 @@ OBJDIRS += $(LIBFDT_objdir)
>
> # EFI App
> ifeq ($(CONFIG_EFI),y)
> -EFI_ARCH = x86_64
> EFI_CFLAGS := -DCONFIG_EFI
> # The following CFLAGS and LDFLAGS come from:
> # - GNU-EFI/Makefile.defaults
> # - GNU-EFI/apps/Makefile
> -# Function calls must include the number of arguments passed to the functions
> -# More details: https://wiki.osdev.org/GNU-EFI
> -EFI_CFLAGS += -maccumulate-outgoing-args
> # GCC defines wchar to be 32 bits, but EFI expects 16 bits
> EFI_CFLAGS += -fshort-wchar
> # EFI applications use PIC as they are loaded to dynamic addresses, not a fixed
> diff --git a/x86/Makefile.x86_64 b/x86/Makefile.x86_64
> index f483dead..2771a6fa 100644
> --- a/x86/Makefile.x86_64
> +++ b/x86/Makefile.x86_64
> @@ -2,6 +2,10 @@ cstart.o = $(TEST_DIR)/cstart64.o
> bits = 64
> ldarch = elf64-x86-64
> ifeq ($(CONFIG_EFI),y)
> +# Function calls must include the number of arguments passed to the functions
> +# More details: https://wiki.osdev.org/GNU-EFI
> +CFLAGS += -maccumulate-outgoing-args
> +
> exe = efi
> bin = so
> FORMAT = efi-app-x86_64
--
Shaoqin
^ permalink raw reply [flat|nested] 52+ messages in thread
* [kvm-unit-tests PATCH v5 03/29] lib: Apply Lindent to acpi.{c,h}
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 01/29] lib: Move acpi header and implementation to lib Nikos Nikoleris
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 02/29] x86: Move x86_64-specific EFI CFLAGS to x86_64 Makefile Nikos Nikoleris
@ 2023-04-28 12:03 ` Nikos Nikoleris
2023-05-01 12:44 ` Shaoqin Huang
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 04/29] lib: Fix style for acpi.{c,h} Nikos Nikoleris
` (27 subsequent siblings)
30 siblings, 1 reply; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-28 12:03 UTC (permalink / raw)
To: kvm, kvmarm, andrew.jones; +Cc: pbonzini, alexandru.elisei, ricarkol
The change was done by modifying Linux's scripts/Lindent to use 100
columns instead of 80.
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
---
lib/acpi.h | 157 ++++++++++++++++++++++++++---------------------------
lib/acpi.c | 70 ++++++++++++------------
2 files changed, 111 insertions(+), 116 deletions(-)
diff --git a/lib/acpi.h b/lib/acpi.h
index 1e89840c..b67bbe19 100644
--- a/lib/acpi.h
+++ b/lib/acpi.h
@@ -3,7 +3,7 @@
#include "libcflat.h"
-#define ACPI_SIGNATURE(c1, c2, c3, c4) \
+#define ACPI_SIGNATURE(c1, c2, c3, c4) \
((c1) | ((c2) << 8) | ((c3) << 16) | ((c4) << 24))
#define RSDP_SIGNATURE ACPI_SIGNATURE('R','S','D','P')
@@ -11,102 +11,99 @@
#define FACP_SIGNATURE ACPI_SIGNATURE('F','A','C','P')
#define FACS_SIGNATURE ACPI_SIGNATURE('F','A','C','S')
-
-#define ACPI_SIGNATURE_8BYTE(c1, c2, c3, c4, c5, c6, c7, c8) \
- ((uint64_t)(ACPI_SIGNATURE(c1, c2, c3, c4))) | \
+#define ACPI_SIGNATURE_8BYTE(c1, c2, c3, c4, c5, c6, c7, c8) \
+ ((uint64_t)(ACPI_SIGNATURE(c1, c2, c3, c4))) | \
((uint64_t)(ACPI_SIGNATURE(c5, c6, c7, c8)) << 32)
#define RSDP_SIGNATURE_8BYTE (ACPI_SIGNATURE_8BYTE('R', 'S', 'D', ' ', 'P', 'T', 'R', ' '))
-struct rsdp_descriptor { /* Root System Descriptor Pointer */
- u64 signature; /* ACPI signature, contains "RSD PTR " */
- u8 checksum; /* To make sum of struct == 0 */
- u8 oem_id [6]; /* OEM identification */
- u8 revision; /* Must be 0 for 1.0, 2 for 2.0 */
- u32 rsdt_physical_address; /* 32-bit physical address of RSDT */
- u32 length; /* XSDT Length in bytes including hdr */
- u64 xsdt_physical_address; /* 64-bit physical address of XSDT */
- u8 extended_checksum; /* Checksum of entire table */
- u8 reserved [3]; /* Reserved field must be 0 */
+struct rsdp_descriptor { /* Root System Descriptor Pointer */
+ u64 signature; /* ACPI signature, contains "RSD PTR " */
+ u8 checksum; /* To make sum of struct == 0 */
+ u8 oem_id[6]; /* OEM identification */
+ u8 revision; /* Must be 0 for 1.0, 2 for 2.0 */
+ u32 rsdt_physical_address; /* 32-bit physical address of RSDT */
+ u32 length; /* XSDT Length in bytes including hdr */
+ u64 xsdt_physical_address; /* 64-bit physical address of XSDT */
+ u8 extended_checksum; /* Checksum of entire table */
+ u8 reserved[3]; /* Reserved field must be 0 */
};
-#define ACPI_TABLE_HEADER_DEF /* ACPI common table header */ \
- u32 signature; /* ACPI signature (4 ASCII characters) */ \
- u32 length; /* Length of table, in bytes, including header */ \
- u8 revision; /* ACPI Specification minor version # */ \
- u8 checksum; /* To make sum of entire table == 0 */ \
- u8 oem_id [6]; /* OEM identification */ \
- u8 oem_table_id [8]; /* OEM table identification */ \
- u32 oem_revision; /* OEM revision number */ \
- u8 asl_compiler_id [4]; /* ASL compiler vendor ID */ \
- u32 asl_compiler_revision; /* ASL compiler revision number */
+#define ACPI_TABLE_HEADER_DEF /* ACPI common table header */ \
+ u32 signature; /* ACPI signature (4 ASCII characters) */ \
+ u32 length; /* Length of table, in bytes, including header */ \
+ u8 revision; /* ACPI Specification minor version # */ \
+ u8 checksum; /* To make sum of entire table == 0 */ \
+ u8 oem_id [6]; /* OEM identification */ \
+ u8 oem_table_id [8]; /* OEM table identification */ \
+ u32 oem_revision; /* OEM revision number */ \
+ u8 asl_compiler_id [4]; /* ASL compiler vendor ID */ \
+ u32 asl_compiler_revision; /* ASL compiler revision number */
struct acpi_table {
- ACPI_TABLE_HEADER_DEF
- char data[0];
+ ACPI_TABLE_HEADER_DEF
+ char data[0];
};
struct rsdt_descriptor_rev1 {
- ACPI_TABLE_HEADER_DEF
- u32 table_offset_entry[0];
+ ACPI_TABLE_HEADER_DEF
+ u32 table_offset_entry[1];
};
-struct fadt_descriptor_rev1
-{
- ACPI_TABLE_HEADER_DEF /* ACPI common table header */
- u32 firmware_ctrl; /* Physical address of FACS */
- u32 dsdt; /* Physical address of DSDT */
- u8 model; /* System Interrupt Model */
- u8 reserved1; /* Reserved */
- u16 sci_int; /* System vector of SCI interrupt */
- u32 smi_cmd; /* Port address of SMI command port */
- u8 acpi_enable; /* Value to write to smi_cmd to enable ACPI */
- u8 acpi_disable; /* Value to write to smi_cmd to disable ACPI */
- u8 S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */
- u8 reserved2; /* Reserved - must be zero */
- u32 pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */
- u32 pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */
- u32 pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */
- u32 pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */
- u32 pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */
- u32 pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */
- u32 gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */
- u32 gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */
- u8 pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */
- u8 pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */
- u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */
- u8 pm_tmr_len; /* Byte Length of ports at pm_tm_blk */
- u8 gpe0_blk_len; /* Byte Length of ports at gpe0_blk */
- u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */
- u8 gpe1_base; /* Offset in gpe model where gpe1 events start */
- u8 reserved3; /* Reserved */
- u16 plvl2_lat; /* Worst case HW latency to enter/exit C2 state */
- u16 plvl3_lat; /* Worst case HW latency to enter/exit C3 state */
- u16 flush_size; /* Size of area read to flush caches */
- u16 flush_stride; /* Stride used in flushing caches */
- u8 duty_offset; /* Bit location of duty cycle field in p_cnt reg */
- u8 duty_width; /* Bit width of duty cycle field in p_cnt reg */
- u8 day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */
- u8 mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */
- u8 century; /* Index to century in RTC CMOS RAM */
- u8 reserved4; /* Reserved */
- u8 reserved4a; /* Reserved */
- u8 reserved4b; /* Reserved */
+struct fadt_descriptor_rev1 {
+ ACPI_TABLE_HEADER_DEF /* ACPI common table header */
+ u32 firmware_ctrl; /* Physical address of FACS */
+ u32 dsdt; /* Physical address of DSDT */
+ u8 model; /* System Interrupt Model */
+ u8 reserved1; /* Reserved */
+ u16 sci_int; /* System vector of SCI interrupt */
+ u32 smi_cmd; /* Port address of SMI command port */
+ u8 acpi_enable; /* Value to write to smi_cmd to enable ACPI */
+ u8 acpi_disable; /* Value to write to smi_cmd to disable ACPI */
+ u8 S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */
+ u8 reserved2; /* Reserved - must be zero */
+ u32 pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */
+ u32 pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */
+ u32 pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */
+ u32 pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */
+ u32 pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */
+ u32 pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */
+ u32 gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */
+ u32 gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */
+ u8 pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */
+ u8 pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */
+ u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */
+ u8 pm_tmr_len; /* Byte Length of ports at pm_tm_blk */
+ u8 gpe0_blk_len; /* Byte Length of ports at gpe0_blk */
+ u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */
+ u8 gpe1_base; /* Offset in gpe model where gpe1 events start */
+ u8 reserved3; /* Reserved */
+ u16 plvl2_lat; /* Worst case HW latency to enter/exit C2 state */
+ u16 plvl3_lat; /* Worst case HW latency to enter/exit C3 state */
+ u16 flush_size; /* Size of area read to flush caches */
+ u16 flush_stride; /* Stride used in flushing caches */
+ u8 duty_offset; /* Bit location of duty cycle field in p_cnt reg */
+ u8 duty_width; /* Bit width of duty cycle field in p_cnt reg */
+ u8 day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */
+ u8 mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */
+ u8 century; /* Index to century in RTC CMOS RAM */
+ u8 reserved4; /* Reserved */
+ u8 reserved4a; /* Reserved */
+ u8 reserved4b; /* Reserved */
};
-struct facs_descriptor_rev1
-{
- u32 signature; /* ACPI Signature */
- u32 length; /* Length of structure, in bytes */
- u32 hardware_signature; /* Hardware configuration signature */
- u32 firmware_waking_vector; /* ACPI OS waking vector */
- u32 global_lock; /* Global Lock */
- u32 S4bios_f : 1; /* Indicates if S4BIOS support is present */
- u32 reserved1 : 31; /* Must be 0 */
- u8 reserved3 [40]; /* Reserved - must be zero */
+struct facs_descriptor_rev1 {
+ u32 signature; /* ACPI Signature */
+ u32 length; /* Length of structure, in bytes */
+ u32 hardware_signature; /* Hardware configuration signature */
+ u32 firmware_waking_vector; /* ACPI OS waking vector */
+ u32 global_lock; /* Global Lock */
+ u32 S4bios_f:1; /* Indicates if S4BIOS support is present */
+ u32 reserved1:31; /* Must be 0 */
+ u8 reserved3[40]; /* Reserved - must be zero */
};
void set_efi_rsdp(struct rsdp_descriptor *rsdp);
-void* find_acpi_table_addr(u32 sig);
+void *find_acpi_table_addr(u32 sig);
#endif
diff --git a/lib/acpi.c b/lib/acpi.c
index de275caf..836156a1 100644
--- a/lib/acpi.c
+++ b/lib/acpi.c
@@ -36,47 +36,45 @@ static struct rsdp_descriptor *get_rsdp(void)
}
#endif /* CONFIG_EFI */
-void* find_acpi_table_addr(u32 sig)
+void *find_acpi_table_addr(u32 sig)
{
- struct rsdp_descriptor *rsdp;
- struct rsdt_descriptor_rev1 *rsdt;
- void *end;
- int i;
+ struct rsdp_descriptor *rsdp;
+ struct rsdt_descriptor_rev1 *rsdt;
+ void *end;
+ int i;
- /* FACS is special... */
- if (sig == FACS_SIGNATURE) {
- struct fadt_descriptor_rev1 *fadt;
- fadt = find_acpi_table_addr(FACP_SIGNATURE);
- if (!fadt) {
- return NULL;
- }
- return (void*)(ulong)fadt->firmware_ctrl;
- }
+ /* FACS is special... */
+ if (sig == FACS_SIGNATURE) {
+ struct fadt_descriptor_rev1 *fadt;
+ fadt = find_acpi_table_addr(FACP_SIGNATURE);
+ if (!fadt)
+ return NULL;
- rsdp = get_rsdp();
- if (rsdp == NULL) {
- printf("Can't find RSDP\n");
- return 0;
- }
+ return (void *)(ulong) fadt->firmware_ctrl;
+ }
- if (sig == RSDP_SIGNATURE) {
- return rsdp;
- }
+ rsdp = get_rsdp();
+ if (rsdp == NULL) {
+ printf("Can't find RSDP\n");
+ return NULL;
+ }
- rsdt = (void*)(ulong)rsdp->rsdt_physical_address;
- if (!rsdt || rsdt->signature != RSDT_SIGNATURE)
- return 0;
+ if (sig == RSDP_SIGNATURE)
+ return rsdp;
- if (sig == RSDT_SIGNATURE) {
- return rsdt;
- }
+ rsdt = (void *)(ulong) rsdp->rsdt_physical_address;
+ if (!rsdt || rsdt->signature != RSDT_SIGNATURE)
+ return NULL;
+
+ if (sig == RSDT_SIGNATURE)
+ return rsdt;
- end = (void*)rsdt + rsdt->length;
- for (i=0; (void*)&rsdt->table_offset_entry[i] < end; i++) {
- struct acpi_table *t = (void*)(ulong)rsdt->table_offset_entry[i];
- if (t && t->signature == sig) {
- return t;
- }
- }
- return NULL;
+ end = (void *)rsdt + rsdt->length;
+ for (i = 0; (void *)&rsdt->table_offset_entry[i] < end; i++) {
+ struct acpi_table *t = (void *)(ulong) rsdt->table_offset_entry[i];
+ if (t && t->signature == sig) {
+ return t;
+ }
+ }
+ return NULL;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* Re: [kvm-unit-tests PATCH v5 03/29] lib: Apply Lindent to acpi.{c,h}
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 03/29] lib: Apply Lindent to acpi.{c,h} Nikos Nikoleris
@ 2023-05-01 12:44 ` Shaoqin Huang
0 siblings, 0 replies; 52+ messages in thread
From: Shaoqin Huang @ 2023-05-01 12:44 UTC (permalink / raw)
To: Nikos Nikoleris, kvm, kvmarm, andrew.jones
Cc: pbonzini, alexandru.elisei, ricarkol
On 4/28/23 20:03, Nikos Nikoleris wrote:
> The change was done by modifying Linux's scripts/Lindent to use 100
> columns instead of 80.
>
> Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Shaoqin Huang <shahuang@redhat.com>
> ---
> lib/acpi.h | 157 ++++++++++++++++++++++++++---------------------------
> lib/acpi.c | 70 ++++++++++++------------
> 2 files changed, 111 insertions(+), 116 deletions(-)
>
> diff --git a/lib/acpi.h b/lib/acpi.h
> index 1e89840c..b67bbe19 100644
> --- a/lib/acpi.h
> +++ b/lib/acpi.h
> @@ -3,7 +3,7 @@
>
> #include "libcflat.h"
>
> -#define ACPI_SIGNATURE(c1, c2, c3, c4) \
> +#define ACPI_SIGNATURE(c1, c2, c3, c4) \
> ((c1) | ((c2) << 8) | ((c3) << 16) | ((c4) << 24))
>
> #define RSDP_SIGNATURE ACPI_SIGNATURE('R','S','D','P')
> @@ -11,102 +11,99 @@
> #define FACP_SIGNATURE ACPI_SIGNATURE('F','A','C','P')
> #define FACS_SIGNATURE ACPI_SIGNATURE('F','A','C','S')
>
> -
> -#define ACPI_SIGNATURE_8BYTE(c1, c2, c3, c4, c5, c6, c7, c8) \
> - ((uint64_t)(ACPI_SIGNATURE(c1, c2, c3, c4))) | \
> +#define ACPI_SIGNATURE_8BYTE(c1, c2, c3, c4, c5, c6, c7, c8) \
> + ((uint64_t)(ACPI_SIGNATURE(c1, c2, c3, c4))) | \
> ((uint64_t)(ACPI_SIGNATURE(c5, c6, c7, c8)) << 32)
>
> #define RSDP_SIGNATURE_8BYTE (ACPI_SIGNATURE_8BYTE('R', 'S', 'D', ' ', 'P', 'T', 'R', ' '))
>
> -struct rsdp_descriptor { /* Root System Descriptor Pointer */
> - u64 signature; /* ACPI signature, contains "RSD PTR " */
> - u8 checksum; /* To make sum of struct == 0 */
> - u8 oem_id [6]; /* OEM identification */
> - u8 revision; /* Must be 0 for 1.0, 2 for 2.0 */
> - u32 rsdt_physical_address; /* 32-bit physical address of RSDT */
> - u32 length; /* XSDT Length in bytes including hdr */
> - u64 xsdt_physical_address; /* 64-bit physical address of XSDT */
> - u8 extended_checksum; /* Checksum of entire table */
> - u8 reserved [3]; /* Reserved field must be 0 */
> +struct rsdp_descriptor { /* Root System Descriptor Pointer */
> + u64 signature; /* ACPI signature, contains "RSD PTR " */
> + u8 checksum; /* To make sum of struct == 0 */
> + u8 oem_id[6]; /* OEM identification */
> + u8 revision; /* Must be 0 for 1.0, 2 for 2.0 */
> + u32 rsdt_physical_address; /* 32-bit physical address of RSDT */
> + u32 length; /* XSDT Length in bytes including hdr */
> + u64 xsdt_physical_address; /* 64-bit physical address of XSDT */
> + u8 extended_checksum; /* Checksum of entire table */
> + u8 reserved[3]; /* Reserved field must be 0 */
> };
>
> -#define ACPI_TABLE_HEADER_DEF /* ACPI common table header */ \
> - u32 signature; /* ACPI signature (4 ASCII characters) */ \
> - u32 length; /* Length of table, in bytes, including header */ \
> - u8 revision; /* ACPI Specification minor version # */ \
> - u8 checksum; /* To make sum of entire table == 0 */ \
> - u8 oem_id [6]; /* OEM identification */ \
> - u8 oem_table_id [8]; /* OEM table identification */ \
> - u32 oem_revision; /* OEM revision number */ \
> - u8 asl_compiler_id [4]; /* ASL compiler vendor ID */ \
> - u32 asl_compiler_revision; /* ASL compiler revision number */
> +#define ACPI_TABLE_HEADER_DEF /* ACPI common table header */ \
> + u32 signature; /* ACPI signature (4 ASCII characters) */ \
> + u32 length; /* Length of table, in bytes, including header */ \
> + u8 revision; /* ACPI Specification minor version # */ \
> + u8 checksum; /* To make sum of entire table == 0 */ \
> + u8 oem_id [6]; /* OEM identification */ \
> + u8 oem_table_id [8]; /* OEM table identification */ \
> + u32 oem_revision; /* OEM revision number */ \
> + u8 asl_compiler_id [4]; /* ASL compiler vendor ID */ \
> + u32 asl_compiler_revision; /* ASL compiler revision number */
>
> struct acpi_table {
> - ACPI_TABLE_HEADER_DEF
> - char data[0];
> + ACPI_TABLE_HEADER_DEF
> + char data[0];
> };
>
> struct rsdt_descriptor_rev1 {
> - ACPI_TABLE_HEADER_DEF
> - u32 table_offset_entry[0];
> + ACPI_TABLE_HEADER_DEF
> + u32 table_offset_entry[1];
> };
>
> -struct fadt_descriptor_rev1
> -{
> - ACPI_TABLE_HEADER_DEF /* ACPI common table header */
> - u32 firmware_ctrl; /* Physical address of FACS */
> - u32 dsdt; /* Physical address of DSDT */
> - u8 model; /* System Interrupt Model */
> - u8 reserved1; /* Reserved */
> - u16 sci_int; /* System vector of SCI interrupt */
> - u32 smi_cmd; /* Port address of SMI command port */
> - u8 acpi_enable; /* Value to write to smi_cmd to enable ACPI */
> - u8 acpi_disable; /* Value to write to smi_cmd to disable ACPI */
> - u8 S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */
> - u8 reserved2; /* Reserved - must be zero */
> - u32 pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */
> - u32 pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */
> - u32 pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */
> - u32 pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */
> - u32 pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */
> - u32 pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */
> - u32 gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */
> - u32 gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */
> - u8 pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */
> - u8 pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */
> - u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */
> - u8 pm_tmr_len; /* Byte Length of ports at pm_tm_blk */
> - u8 gpe0_blk_len; /* Byte Length of ports at gpe0_blk */
> - u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */
> - u8 gpe1_base; /* Offset in gpe model where gpe1 events start */
> - u8 reserved3; /* Reserved */
> - u16 plvl2_lat; /* Worst case HW latency to enter/exit C2 state */
> - u16 plvl3_lat; /* Worst case HW latency to enter/exit C3 state */
> - u16 flush_size; /* Size of area read to flush caches */
> - u16 flush_stride; /* Stride used in flushing caches */
> - u8 duty_offset; /* Bit location of duty cycle field in p_cnt reg */
> - u8 duty_width; /* Bit width of duty cycle field in p_cnt reg */
> - u8 day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */
> - u8 mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */
> - u8 century; /* Index to century in RTC CMOS RAM */
> - u8 reserved4; /* Reserved */
> - u8 reserved4a; /* Reserved */
> - u8 reserved4b; /* Reserved */
> +struct fadt_descriptor_rev1 {
> + ACPI_TABLE_HEADER_DEF /* ACPI common table header */
> + u32 firmware_ctrl; /* Physical address of FACS */
> + u32 dsdt; /* Physical address of DSDT */
> + u8 model; /* System Interrupt Model */
> + u8 reserved1; /* Reserved */
> + u16 sci_int; /* System vector of SCI interrupt */
> + u32 smi_cmd; /* Port address of SMI command port */
> + u8 acpi_enable; /* Value to write to smi_cmd to enable ACPI */
> + u8 acpi_disable; /* Value to write to smi_cmd to disable ACPI */
> + u8 S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */
> + u8 reserved2; /* Reserved - must be zero */
> + u32 pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */
> + u32 pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */
> + u32 pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */
> + u32 pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */
> + u32 pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */
> + u32 pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */
> + u32 gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */
> + u32 gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */
> + u8 pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */
> + u8 pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */
> + u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */
> + u8 pm_tmr_len; /* Byte Length of ports at pm_tm_blk */
> + u8 gpe0_blk_len; /* Byte Length of ports at gpe0_blk */
> + u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */
> + u8 gpe1_base; /* Offset in gpe model where gpe1 events start */
> + u8 reserved3; /* Reserved */
> + u16 plvl2_lat; /* Worst case HW latency to enter/exit C2 state */
> + u16 plvl3_lat; /* Worst case HW latency to enter/exit C3 state */
> + u16 flush_size; /* Size of area read to flush caches */
> + u16 flush_stride; /* Stride used in flushing caches */
> + u8 duty_offset; /* Bit location of duty cycle field in p_cnt reg */
> + u8 duty_width; /* Bit width of duty cycle field in p_cnt reg */
> + u8 day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */
> + u8 mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */
> + u8 century; /* Index to century in RTC CMOS RAM */
> + u8 reserved4; /* Reserved */
> + u8 reserved4a; /* Reserved */
> + u8 reserved4b; /* Reserved */
> };
>
> -struct facs_descriptor_rev1
> -{
> - u32 signature; /* ACPI Signature */
> - u32 length; /* Length of structure, in bytes */
> - u32 hardware_signature; /* Hardware configuration signature */
> - u32 firmware_waking_vector; /* ACPI OS waking vector */
> - u32 global_lock; /* Global Lock */
> - u32 S4bios_f : 1; /* Indicates if S4BIOS support is present */
> - u32 reserved1 : 31; /* Must be 0 */
> - u8 reserved3 [40]; /* Reserved - must be zero */
> +struct facs_descriptor_rev1 {
> + u32 signature; /* ACPI Signature */
> + u32 length; /* Length of structure, in bytes */
> + u32 hardware_signature; /* Hardware configuration signature */
> + u32 firmware_waking_vector; /* ACPI OS waking vector */
> + u32 global_lock; /* Global Lock */
> + u32 S4bios_f:1; /* Indicates if S4BIOS support is present */
> + u32 reserved1:31; /* Must be 0 */
> + u8 reserved3[40]; /* Reserved - must be zero */
> };
>
> void set_efi_rsdp(struct rsdp_descriptor *rsdp);
> -void* find_acpi_table_addr(u32 sig);
> +void *find_acpi_table_addr(u32 sig);
>
> #endif
> diff --git a/lib/acpi.c b/lib/acpi.c
> index de275caf..836156a1 100644
> --- a/lib/acpi.c
> +++ b/lib/acpi.c
> @@ -36,47 +36,45 @@ static struct rsdp_descriptor *get_rsdp(void)
> }
> #endif /* CONFIG_EFI */
>
> -void* find_acpi_table_addr(u32 sig)
> +void *find_acpi_table_addr(u32 sig)
> {
> - struct rsdp_descriptor *rsdp;
> - struct rsdt_descriptor_rev1 *rsdt;
> - void *end;
> - int i;
> + struct rsdp_descriptor *rsdp;
> + struct rsdt_descriptor_rev1 *rsdt;
> + void *end;
> + int i;
>
> - /* FACS is special... */
> - if (sig == FACS_SIGNATURE) {
> - struct fadt_descriptor_rev1 *fadt;
> - fadt = find_acpi_table_addr(FACP_SIGNATURE);
> - if (!fadt) {
> - return NULL;
> - }
> - return (void*)(ulong)fadt->firmware_ctrl;
> - }
> + /* FACS is special... */
> + if (sig == FACS_SIGNATURE) {
> + struct fadt_descriptor_rev1 *fadt;
> + fadt = find_acpi_table_addr(FACP_SIGNATURE);
> + if (!fadt)
> + return NULL;
>
> - rsdp = get_rsdp();
> - if (rsdp == NULL) {
> - printf("Can't find RSDP\n");
> - return 0;
> - }
> + return (void *)(ulong) fadt->firmware_ctrl;
> + }
>
> - if (sig == RSDP_SIGNATURE) {
> - return rsdp;
> - }
> + rsdp = get_rsdp();
> + if (rsdp == NULL) {
> + printf("Can't find RSDP\n");
> + return NULL;
> + }
>
> - rsdt = (void*)(ulong)rsdp->rsdt_physical_address;
> - if (!rsdt || rsdt->signature != RSDT_SIGNATURE)
> - return 0;
> + if (sig == RSDP_SIGNATURE)
> + return rsdp;
>
> - if (sig == RSDT_SIGNATURE) {
> - return rsdt;
> - }
> + rsdt = (void *)(ulong) rsdp->rsdt_physical_address;
> + if (!rsdt || rsdt->signature != RSDT_SIGNATURE)
> + return NULL;
> +
> + if (sig == RSDT_SIGNATURE)
> + return rsdt;
>
> - end = (void*)rsdt + rsdt->length;
> - for (i=0; (void*)&rsdt->table_offset_entry[i] < end; i++) {
> - struct acpi_table *t = (void*)(ulong)rsdt->table_offset_entry[i];
> - if (t && t->signature == sig) {
> - return t;
> - }
> - }
> - return NULL;
> + end = (void *)rsdt + rsdt->length;
> + for (i = 0; (void *)&rsdt->table_offset_entry[i] < end; i++) {
> + struct acpi_table *t = (void *)(ulong) rsdt->table_offset_entry[i];
> + if (t && t->signature == sig) {
> + return t;
> + }
> + }
> + return NULL;
> }
--
Shaoqin
^ permalink raw reply [flat|nested] 52+ messages in thread
* [kvm-unit-tests PATCH v5 04/29] lib: Fix style for acpi.{c,h}
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
` (2 preceding siblings ...)
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 03/29] lib: Apply Lindent to acpi.{c,h} Nikos Nikoleris
@ 2023-04-28 12:03 ` Nikos Nikoleris
2023-05-01 12:50 ` Shaoqin Huang
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 05/29] lib/acpi: Convert table names to Linux style Nikos Nikoleris
` (26 subsequent siblings)
30 siblings, 1 reply; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-28 12:03 UTC (permalink / raw)
To: kvm, kvmarm, andrew.jones; +Cc: pbonzini, alexandru.elisei, ricarkol
Manually fix style issues to make the files consistent with the kernel
coding style.
Zero-length array members have been replaced with flexible array members
(for details about the motivation, consult
Documentation/process/deprecated.rst in the Linux tree, the section about
zero-length and one-element arrays).
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
[ Alex E: changes other than indentation ]
---
lib/acpi.h | 18 +++++++++---------
lib/acpi.c | 16 ++++++++--------
2 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/lib/acpi.h b/lib/acpi.h
index b67bbe19..2da49451 100644
--- a/lib/acpi.h
+++ b/lib/acpi.h
@@ -3,7 +3,7 @@
#include "libcflat.h"
-#define ACPI_SIGNATURE(c1, c2, c3, c4) \
+#define ACPI_SIGNATURE(c1, c2, c3, c4) \
((c1) | ((c2) << 8) | ((c3) << 16) | ((c4) << 24))
#define RSDP_SIGNATURE ACPI_SIGNATURE('R','S','D','P')
@@ -11,9 +11,9 @@
#define FACP_SIGNATURE ACPI_SIGNATURE('F','A','C','P')
#define FACS_SIGNATURE ACPI_SIGNATURE('F','A','C','S')
-#define ACPI_SIGNATURE_8BYTE(c1, c2, c3, c4, c5, c6, c7, c8) \
- ((uint64_t)(ACPI_SIGNATURE(c1, c2, c3, c4))) | \
- ((uint64_t)(ACPI_SIGNATURE(c5, c6, c7, c8)) << 32)
+#define ACPI_SIGNATURE_8BYTE(c1, c2, c3, c4, c5, c6, c7, c8) \
+ (((uint64_t)(ACPI_SIGNATURE(c1, c2, c3, c4))) | \
+ ((uint64_t)(ACPI_SIGNATURE(c5, c6, c7, c8)) << 32))
#define RSDP_SIGNATURE_8BYTE (ACPI_SIGNATURE_8BYTE('R', 'S', 'D', ' ', 'P', 'T', 'R', ' '))
@@ -34,20 +34,20 @@ struct rsdp_descriptor { /* Root System Descriptor Pointer */
u32 length; /* Length of table, in bytes, including header */ \
u8 revision; /* ACPI Specification minor version # */ \
u8 checksum; /* To make sum of entire table == 0 */ \
- u8 oem_id [6]; /* OEM identification */ \
- u8 oem_table_id [8]; /* OEM table identification */ \
+ u8 oem_id[6]; /* OEM identification */ \
+ u8 oem_table_id[8]; /* OEM table identification */ \
u32 oem_revision; /* OEM revision number */ \
- u8 asl_compiler_id [4]; /* ASL compiler vendor ID */ \
+ u8 asl_compiler_id[4]; /* ASL compiler vendor ID */ \
u32 asl_compiler_revision; /* ASL compiler revision number */
struct acpi_table {
ACPI_TABLE_HEADER_DEF
- char data[0];
+ char data[];
};
struct rsdt_descriptor_rev1 {
ACPI_TABLE_HEADER_DEF
- u32 table_offset_entry[1];
+ u32 table_offset_entry[];
};
struct fadt_descriptor_rev1 {
diff --git a/lib/acpi.c b/lib/acpi.c
index 836156a1..3f87711a 100644
--- a/lib/acpi.c
+++ b/lib/acpi.c
@@ -11,9 +11,9 @@ void set_efi_rsdp(struct rsdp_descriptor *rsdp)
static struct rsdp_descriptor *get_rsdp(void)
{
- if (efi_rsdp == NULL) {
+ if (efi_rsdp == NULL)
printf("Can't find RSDP from UEFI, maybe set_efi_rsdp() was not called\n");
- }
+
return efi_rsdp;
}
#else
@@ -28,9 +28,8 @@ static struct rsdp_descriptor *get_rsdp(void)
break;
}
- if (addr == 0x100000) {
+ if (addr == 0x100000)
return NULL;
- }
return rsdp;
}
@@ -38,18 +37,18 @@ static struct rsdp_descriptor *get_rsdp(void)
void *find_acpi_table_addr(u32 sig)
{
- struct rsdp_descriptor *rsdp;
struct rsdt_descriptor_rev1 *rsdt;
+ struct rsdp_descriptor *rsdp;
void *end;
int i;
/* FACS is special... */
if (sig == FACS_SIGNATURE) {
struct fadt_descriptor_rev1 *fadt;
+
fadt = find_acpi_table_addr(FACP_SIGNATURE);
if (!fadt)
return NULL;
-
return (void *)(ulong) fadt->firmware_ctrl;
}
@@ -72,9 +71,10 @@ void *find_acpi_table_addr(u32 sig)
end = (void *)rsdt + rsdt->length;
for (i = 0; (void *)&rsdt->table_offset_entry[i] < end; i++) {
struct acpi_table *t = (void *)(ulong) rsdt->table_offset_entry[i];
- if (t && t->signature == sig) {
+
+ if (t && t->signature == sig)
return t;
- }
}
+
return NULL;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* Re: [kvm-unit-tests PATCH v5 04/29] lib: Fix style for acpi.{c,h}
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 04/29] lib: Fix style for acpi.{c,h} Nikos Nikoleris
@ 2023-05-01 12:50 ` Shaoqin Huang
0 siblings, 0 replies; 52+ messages in thread
From: Shaoqin Huang @ 2023-05-01 12:50 UTC (permalink / raw)
To: Nikos Nikoleris, kvm, kvmarm, andrew.jones
Cc: pbonzini, alexandru.elisei, ricarkol
On 4/28/23 20:03, Nikos Nikoleris wrote:
> Manually fix style issues to make the files consistent with the kernel
> coding style.
>
> Zero-length array members have been replaced with flexible array members
> (for details about the motivation, consult
> Documentation/process/deprecated.rst in the Linux tree, the section about
> zero-length and one-element arrays).
>
> Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Shaoqin Huang <shahuang@redhat.com>
> [ Alex E: changes other than indentation ]
> ---
> lib/acpi.h | 18 +++++++++---------
> lib/acpi.c | 16 ++++++++--------
> 2 files changed, 17 insertions(+), 17 deletions(-)
>
> diff --git a/lib/acpi.h b/lib/acpi.h
> index b67bbe19..2da49451 100644
> --- a/lib/acpi.h
> +++ b/lib/acpi.h
> @@ -3,7 +3,7 @@
>
> #include "libcflat.h"
>
> -#define ACPI_SIGNATURE(c1, c2, c3, c4) \
> +#define ACPI_SIGNATURE(c1, c2, c3, c4) \
> ((c1) | ((c2) << 8) | ((c3) << 16) | ((c4) << 24))
>
> #define RSDP_SIGNATURE ACPI_SIGNATURE('R','S','D','P')
> @@ -11,9 +11,9 @@
> #define FACP_SIGNATURE ACPI_SIGNATURE('F','A','C','P')
> #define FACS_SIGNATURE ACPI_SIGNATURE('F','A','C','S')
>
> -#define ACPI_SIGNATURE_8BYTE(c1, c2, c3, c4, c5, c6, c7, c8) \
> - ((uint64_t)(ACPI_SIGNATURE(c1, c2, c3, c4))) | \
> - ((uint64_t)(ACPI_SIGNATURE(c5, c6, c7, c8)) << 32)
> +#define ACPI_SIGNATURE_8BYTE(c1, c2, c3, c4, c5, c6, c7, c8) \
> + (((uint64_t)(ACPI_SIGNATURE(c1, c2, c3, c4))) | \
> + ((uint64_t)(ACPI_SIGNATURE(c5, c6, c7, c8)) << 32))
>
> #define RSDP_SIGNATURE_8BYTE (ACPI_SIGNATURE_8BYTE('R', 'S', 'D', ' ', 'P', 'T', 'R', ' '))
>
> @@ -34,20 +34,20 @@ struct rsdp_descriptor { /* Root System Descriptor Pointer */
> u32 length; /* Length of table, in bytes, including header */ \
> u8 revision; /* ACPI Specification minor version # */ \
> u8 checksum; /* To make sum of entire table == 0 */ \
> - u8 oem_id [6]; /* OEM identification */ \
> - u8 oem_table_id [8]; /* OEM table identification */ \
> + u8 oem_id[6]; /* OEM identification */ \
> + u8 oem_table_id[8]; /* OEM table identification */ \
> u32 oem_revision; /* OEM revision number */ \
> - u8 asl_compiler_id [4]; /* ASL compiler vendor ID */ \
> + u8 asl_compiler_id[4]; /* ASL compiler vendor ID */ \
> u32 asl_compiler_revision; /* ASL compiler revision number */
>
> struct acpi_table {
> ACPI_TABLE_HEADER_DEF
> - char data[0];
> + char data[];
> };
>
> struct rsdt_descriptor_rev1 {
> ACPI_TABLE_HEADER_DEF
> - u32 table_offset_entry[1];
> + u32 table_offset_entry[];
> };
>
> struct fadt_descriptor_rev1 {
> diff --git a/lib/acpi.c b/lib/acpi.c
> index 836156a1..3f87711a 100644
> --- a/lib/acpi.c
> +++ b/lib/acpi.c
> @@ -11,9 +11,9 @@ void set_efi_rsdp(struct rsdp_descriptor *rsdp)
>
> static struct rsdp_descriptor *get_rsdp(void)
> {
> - if (efi_rsdp == NULL) {
> + if (efi_rsdp == NULL)
> printf("Can't find RSDP from UEFI, maybe set_efi_rsdp() was not called\n");
> - }
> +
> return efi_rsdp;
> }
> #else
> @@ -28,9 +28,8 @@ static struct rsdp_descriptor *get_rsdp(void)
> break;
> }
>
> - if (addr == 0x100000) {
> + if (addr == 0x100000)
> return NULL;
> - }
>
> return rsdp;
> }
> @@ -38,18 +37,18 @@ static struct rsdp_descriptor *get_rsdp(void)
>
> void *find_acpi_table_addr(u32 sig)
> {
> - struct rsdp_descriptor *rsdp;
> struct rsdt_descriptor_rev1 *rsdt;
> + struct rsdp_descriptor *rsdp;
> void *end;
> int i;
>
> /* FACS is special... */
> if (sig == FACS_SIGNATURE) {
> struct fadt_descriptor_rev1 *fadt;
> +
> fadt = find_acpi_table_addr(FACP_SIGNATURE);
> if (!fadt)
> return NULL;
> -
> return (void *)(ulong) fadt->firmware_ctrl;
> }
>
> @@ -72,9 +71,10 @@ void *find_acpi_table_addr(u32 sig)
> end = (void *)rsdt + rsdt->length;
> for (i = 0; (void *)&rsdt->table_offset_entry[i] < end; i++) {
> struct acpi_table *t = (void *)(ulong) rsdt->table_offset_entry[i];
> - if (t && t->signature == sig) {
> +
> + if (t && t->signature == sig)
> return t;
> - }
> }
> +
> return NULL;
> }
--
Shaoqin
^ permalink raw reply [flat|nested] 52+ messages in thread
* [kvm-unit-tests PATCH v5 05/29] lib/acpi: Convert table names to Linux style
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
` (3 preceding siblings ...)
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 04/29] lib: Fix style for acpi.{c,h} Nikos Nikoleris
@ 2023-04-28 12:03 ` Nikos Nikoleris
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 06/29] x86: Avoid references to fields of ACPI tables Nikos Nikoleris
` (25 subsequent siblings)
30 siblings, 0 replies; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-28 12:03 UTC (permalink / raw)
To: kvm, kvmarm, andrew.jones; +Cc: Alexandru Elisei, pbonzini, ricarkol
From: Alexandru Elisei <alexandru.elisei@arm.com>
kvm-unit-tests is about to import several table struct definitions from
Linux, convert the names of the existing tables to follow the Linux style.
This is purely a cosmetic change and no functional change is intended.
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
---
lib/acpi.h | 10 +++++-----
lib/acpi.c | 16 ++++++++--------
lib/x86/setup.c | 2 +-
x86/s3.c | 4 ++--
x86/vmexit.c | 2 +-
5 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/lib/acpi.h b/lib/acpi.h
index 2da49451..f9a344e9 100644
--- a/lib/acpi.h
+++ b/lib/acpi.h
@@ -17,7 +17,7 @@
#define RSDP_SIGNATURE_8BYTE (ACPI_SIGNATURE_8BYTE('R', 'S', 'D', ' ', 'P', 'T', 'R', ' '))
-struct rsdp_descriptor { /* Root System Descriptor Pointer */
+struct acpi_table_rsdp { /* Root System Descriptor Pointer */
u64 signature; /* ACPI signature, contains "RSD PTR " */
u8 checksum; /* To make sum of struct == 0 */
u8 oem_id[6]; /* OEM identification */
@@ -45,12 +45,12 @@ struct acpi_table {
char data[];
};
-struct rsdt_descriptor_rev1 {
+struct acpi_table_rsdt_rev1 {
ACPI_TABLE_HEADER_DEF
u32 table_offset_entry[];
};
-struct fadt_descriptor_rev1 {
+struct acpi_table_fadt_rev1 {
ACPI_TABLE_HEADER_DEF /* ACPI common table header */
u32 firmware_ctrl; /* Physical address of FACS */
u32 dsdt; /* Physical address of DSDT */
@@ -92,7 +92,7 @@ struct fadt_descriptor_rev1 {
u8 reserved4b; /* Reserved */
};
-struct facs_descriptor_rev1 {
+struct acpi_table_facs_rev1 {
u32 signature; /* ACPI Signature */
u32 length; /* Length of structure, in bytes */
u32 hardware_signature; /* Hardware configuration signature */
@@ -103,7 +103,7 @@ struct facs_descriptor_rev1 {
u8 reserved3[40]; /* Reserved - must be zero */
};
-void set_efi_rsdp(struct rsdp_descriptor *rsdp);
+void set_efi_rsdp(struct acpi_table_rsdp *rsdp);
void *find_acpi_table_addr(u32 sig);
#endif
diff --git a/lib/acpi.c b/lib/acpi.c
index 3f87711a..166ffd14 100644
--- a/lib/acpi.c
+++ b/lib/acpi.c
@@ -2,14 +2,14 @@
#include "acpi.h"
#ifdef CONFIG_EFI
-struct rsdp_descriptor *efi_rsdp = NULL;
+struct acpi_table_rsdp *efi_rsdp = NULL;
-void set_efi_rsdp(struct rsdp_descriptor *rsdp)
+void set_efi_rsdp(struct acpi_table_rsdp *rsdp)
{
efi_rsdp = rsdp;
}
-static struct rsdp_descriptor *get_rsdp(void)
+static struct acpi_table_rsdp *get_rsdp(void)
{
if (efi_rsdp == NULL)
printf("Can't find RSDP from UEFI, maybe set_efi_rsdp() was not called\n");
@@ -17,9 +17,9 @@ static struct rsdp_descriptor *get_rsdp(void)
return efi_rsdp;
}
#else
-static struct rsdp_descriptor *get_rsdp(void)
+static struct acpi_table_rsdp *get_rsdp(void)
{
- struct rsdp_descriptor *rsdp;
+ struct acpi_table_rsdp *rsdp;
unsigned long addr;
for (addr = 0xe0000; addr < 0x100000; addr += 16) {
@@ -37,14 +37,14 @@ static struct rsdp_descriptor *get_rsdp(void)
void *find_acpi_table_addr(u32 sig)
{
- struct rsdt_descriptor_rev1 *rsdt;
- struct rsdp_descriptor *rsdp;
+ struct acpi_table_rsdt_rev1 *rsdt;
+ struct acpi_table_rsdp *rsdp;
void *end;
int i;
/* FACS is special... */
if (sig == FACS_SIGNATURE) {
- struct fadt_descriptor_rev1 *fadt;
+ struct acpi_table_fadt_rev1 *fadt;
fadt = find_acpi_table_addr(FACP_SIGNATURE);
if (!fadt)
diff --git a/lib/x86/setup.c b/lib/x86/setup.c
index dd150300..d509a248 100644
--- a/lib/x86/setup.c
+++ b/lib/x86/setup.c
@@ -245,7 +245,7 @@ static efi_status_t setup_memory_allocator(efi_bootinfo_t *efi_bootinfo)
static efi_status_t setup_rsdp(efi_bootinfo_t *efi_bootinfo)
{
efi_status_t status;
- struct rsdp_descriptor *rsdp;
+ struct acpi_table_rsdp *rsdp;
/*
* RSDP resides in an EFI_ACPI_RECLAIM_MEMORY region, which is not used
diff --git a/x86/s3.c b/x86/s3.c
index 378d37ae..96db728c 100644
--- a/x86/s3.c
+++ b/x86/s3.c
@@ -4,7 +4,7 @@
static u32* find_resume_vector_addr(void)
{
- struct facs_descriptor_rev1 *facs = find_acpi_table_addr(FACS_SIGNATURE);
+ struct acpi_table_facs_rev1 *facs = find_acpi_table_addr(FACS_SIGNATURE);
if (!facs)
return 0;
printf("FACS is at %p\n", facs);
@@ -39,7 +39,7 @@ extern char resume_start, resume_end;
int main(int argc, char **argv)
{
- struct fadt_descriptor_rev1 *fadt = find_acpi_table_addr(FACP_SIGNATURE);
+ struct acpi_table_fadt_rev1 *fadt = find_acpi_table_addr(FACP_SIGNATURE);
volatile u32 *resume_vector_ptr = find_resume_vector_addr();
char *addr, *resume_vec = (void*)0x1000;
diff --git a/x86/vmexit.c b/x86/vmexit.c
index 9260accc..12234f9e 100644
--- a/x86/vmexit.c
+++ b/x86/vmexit.c
@@ -206,7 +206,7 @@ int pm_tmr_blk;
static void inl_pmtimer(void)
{
if (!pm_tmr_blk) {
- struct fadt_descriptor_rev1 *fadt;
+ struct acpi_table_fadt_rev1 *fadt;
fadt = find_acpi_table_addr(FACP_SIGNATURE);
pm_tmr_blk = fadt->pm_tmr_blk;
--
2.25.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [kvm-unit-tests PATCH v5 06/29] x86: Avoid references to fields of ACPI tables
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
` (4 preceding siblings ...)
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 05/29] lib/acpi: Convert table names to Linux style Nikos Nikoleris
@ 2023-04-28 12:03 ` Nikos Nikoleris
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 07/29] lib/acpi: Ensure all struct definition for ACPI tables are packed Nikos Nikoleris
` (24 subsequent siblings)
30 siblings, 0 replies; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-28 12:03 UTC (permalink / raw)
To: kvm, kvmarm, andrew.jones; +Cc: pbonzini, alexandru.elisei, ricarkol
ACPI table definitions in <acpi.h> have to be packed. However, once
we do that, direct references to members of the packed struct might
result in unaligned pointers and gcc complains about them. This change
modifies the code to avoid such references in preparation for making
the APCI table definitions packed.
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
---
x86/s3.c | 17 +++++------------
1 file changed, 5 insertions(+), 12 deletions(-)
diff --git a/x86/s3.c b/x86/s3.c
index 96db728c..910c57fb 100644
--- a/x86/s3.c
+++ b/x86/s3.c
@@ -2,15 +2,6 @@
#include "acpi.h"
#include "asm/io.h"
-static u32* find_resume_vector_addr(void)
-{
- struct acpi_table_facs_rev1 *facs = find_acpi_table_addr(FACS_SIGNATURE);
- if (!facs)
- return 0;
- printf("FACS is at %p\n", facs);
- return &facs->firmware_waking_vector;
-}
-
#define RTC_SECONDS_ALARM 1
#define RTC_MINUTES_ALARM 3
#define RTC_HOURS_ALARM 5
@@ -40,12 +31,14 @@ extern char resume_start, resume_end;
int main(int argc, char **argv)
{
struct acpi_table_fadt_rev1 *fadt = find_acpi_table_addr(FACP_SIGNATURE);
- volatile u32 *resume_vector_ptr = find_resume_vector_addr();
+ struct acpi_table_facs_rev1 *facs = find_acpi_table_addr(FACS_SIGNATURE);
char *addr, *resume_vec = (void*)0x1000;
- *resume_vector_ptr = (u32)(ulong)resume_vec;
+ assert(facs);
+ facs->firmware_waking_vector = (u32)(ulong)resume_vec;
- printf("resume vector addr is %p\n", resume_vector_ptr);
+ printf("FACS is at %p\n", facs);
+ printf("resume vector addr is %p\n", &facs->firmware_waking_vector);
for (addr = &resume_start; addr < &resume_end; addr++)
*resume_vec++ = *addr;
printf("copy resume code from %p\n", &resume_start);
--
2.25.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [kvm-unit-tests PATCH v5 07/29] lib/acpi: Ensure all struct definition for ACPI tables are packed
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
` (5 preceding siblings ...)
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 06/29] x86: Avoid references to fields of ACPI tables Nikos Nikoleris
@ 2023-04-28 12:03 ` Nikos Nikoleris
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 08/29] lib/acpi: Add support for the XSDT table Nikos Nikoleris
` (23 subsequent siblings)
30 siblings, 0 replies; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-28 12:03 UTC (permalink / raw)
To: kvm, kvmarm, andrew.jones; +Cc: pbonzini, alexandru.elisei, ricarkol
All ACPI table definitions are provided with precise definitions of
field sizes and offsets, make sure that no compiler optimization can
interfere with the memory layout of the corresponding structs.
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Andrew Jones <andrew.jones@linux.dev>
---
lib/acpi.h | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/lib/acpi.h b/lib/acpi.h
index f9a344e9..53e41c4b 100644
--- a/lib/acpi.h
+++ b/lib/acpi.h
@@ -3,6 +3,12 @@
#include "libcflat.h"
+/*
+ * All tables and structures must be byte-packed to match the ACPI
+ * specification, since the tables are provided by the system firmware.
+ */
+#pragma pack(1)
+
#define ACPI_SIGNATURE(c1, c2, c3, c4) \
((c1) | ((c2) << 8) | ((c3) << 16) | ((c4) << 24))
@@ -103,6 +109,8 @@ struct acpi_table_facs_rev1 {
u8 reserved3[40]; /* Reserved - must be zero */
};
+#pragma pack(0)
+
void set_efi_rsdp(struct acpi_table_rsdp *rsdp);
void *find_acpi_table_addr(u32 sig);
--
2.25.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [kvm-unit-tests PATCH v5 08/29] lib/acpi: Add support for the XSDT table
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
` (6 preceding siblings ...)
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 07/29] lib/acpi: Ensure all struct definition for ACPI tables are packed Nikos Nikoleris
@ 2023-04-28 12:03 ` Nikos Nikoleris
2023-05-01 12:50 ` Shaoqin Huang
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 09/29] lib/acpi: Extend the definition of the FADT table Nikos Nikoleris
` (22 subsequent siblings)
30 siblings, 1 reply; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-28 12:03 UTC (permalink / raw)
To: kvm, kvmarm, andrew.jones; +Cc: pbonzini, alexandru.elisei, ricarkol
XSDT provides pointers to other ACPI tables much like RSDT. However,
contrary to RSDT that provides 32-bit addresses, XSDT provides 64-bit
pointers. ACPI requires that if XSDT is valid then it takes precedence
over RSDT.
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Andrew Jones <andrew.jones@linux.dev>
[ Alex E: Use flexible array member for XSDT struct ]
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
lib/acpi.h | 6 ++++++
lib/acpi.c | 40 ++++++++++++++++++++++++++++++++--------
2 files changed, 38 insertions(+), 8 deletions(-)
diff --git a/lib/acpi.h b/lib/acpi.h
index 53e41c4b..74ba00ac 100644
--- a/lib/acpi.h
+++ b/lib/acpi.h
@@ -14,6 +14,7 @@
#define RSDP_SIGNATURE ACPI_SIGNATURE('R','S','D','P')
#define RSDT_SIGNATURE ACPI_SIGNATURE('R','S','D','T')
+#define XSDT_SIGNATURE ACPI_SIGNATURE('X','S','D','T')
#define FACP_SIGNATURE ACPI_SIGNATURE('F','A','C','P')
#define FACS_SIGNATURE ACPI_SIGNATURE('F','A','C','S')
@@ -56,6 +57,11 @@ struct acpi_table_rsdt_rev1 {
u32 table_offset_entry[];
};
+struct acpi_table_xsdt {
+ ACPI_TABLE_HEADER_DEF
+ u64 table_offset_entry[];
+};
+
struct acpi_table_fadt_rev1 {
ACPI_TABLE_HEADER_DEF /* ACPI common table header */
u32 firmware_ctrl; /* Physical address of FACS */
diff --git a/lib/acpi.c b/lib/acpi.c
index 166ffd14..d35f09a6 100644
--- a/lib/acpi.c
+++ b/lib/acpi.c
@@ -37,7 +37,8 @@ static struct acpi_table_rsdp *get_rsdp(void)
void *find_acpi_table_addr(u32 sig)
{
- struct acpi_table_rsdt_rev1 *rsdt;
+ struct acpi_table_rsdt_rev1 *rsdt = NULL;
+ struct acpi_table_xsdt *xsdt = NULL;
struct acpi_table_rsdp *rsdp;
void *end;
int i;
@@ -62,18 +63,41 @@ void *find_acpi_table_addr(u32 sig)
return rsdp;
rsdt = (void *)(ulong) rsdp->rsdt_physical_address;
- if (!rsdt || rsdt->signature != RSDT_SIGNATURE)
- return NULL;
+ if (rsdt && rsdt->signature != RSDT_SIGNATURE)
+ rsdt = NULL;
if (sig == RSDT_SIGNATURE)
return rsdt;
- end = (void *)rsdt + rsdt->length;
- for (i = 0; (void *)&rsdt->table_offset_entry[i] < end; i++) {
- struct acpi_table *t = (void *)(ulong) rsdt->table_offset_entry[i];
+ if (rsdp->revision >= 2) {
+ xsdt = (void *)rsdp->xsdt_physical_address;
+ if (xsdt && xsdt->signature != XSDT_SIGNATURE)
+ xsdt = NULL;
+ }
- if (t && t->signature == sig)
- return t;
+ if (sig == XSDT_SIGNATURE)
+ return xsdt;
+
+ /*
+ * When the system implements APCI 2.0 and above and XSDT is valid we
+ * have use XSDT to find other ACPI tables, otherwise, we use RSDT.
+ */
+ if (xsdt) {
+ end = (void *)xsdt + xsdt->length;
+ for (i = 0; (void *)&xsdt->table_offset_entry[i] < end; i++) {
+ struct acpi_table *t = (void *)(ulong) xsdt->table_offset_entry[i];
+
+ if (t && t->signature == sig)
+ return t;
+ }
+ } else if (rsdt) {
+ end = (void *)rsdt + rsdt->length;
+ for (i = 0; (void *)&rsdt->table_offset_entry[i] < end; i++) {
+ struct acpi_table *t = (void *)(ulong) rsdt->table_offset_entry[i];
+
+ if (t && t->signature == sig)
+ return t;
+ }
}
return NULL;
--
2.25.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* Re: [kvm-unit-tests PATCH v5 08/29] lib/acpi: Add support for the XSDT table
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 08/29] lib/acpi: Add support for the XSDT table Nikos Nikoleris
@ 2023-05-01 12:50 ` Shaoqin Huang
0 siblings, 0 replies; 52+ messages in thread
From: Shaoqin Huang @ 2023-05-01 12:50 UTC (permalink / raw)
To: Nikos Nikoleris, kvm, kvmarm, andrew.jones
Cc: pbonzini, alexandru.elisei, ricarkol
On 4/28/23 20:03, Nikos Nikoleris wrote:
> XSDT provides pointers to other ACPI tables much like RSDT. However,
> contrary to RSDT that provides 32-bit addresses, XSDT provides 64-bit
> pointers. ACPI requires that if XSDT is valid then it takes precedence
> over RSDT.
>
> Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
> Reviewed-by: Andrew Jones <andrew.jones@linux.dev>
> [ Alex E: Use flexible array member for XSDT struct ]
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
Reviewed-by: Shaoqin Huang <shahuang@redhat.com>
> ---
> lib/acpi.h | 6 ++++++
> lib/acpi.c | 40 ++++++++++++++++++++++++++++++++--------
> 2 files changed, 38 insertions(+), 8 deletions(-)
>
> diff --git a/lib/acpi.h b/lib/acpi.h
> index 53e41c4b..74ba00ac 100644
> --- a/lib/acpi.h
> +++ b/lib/acpi.h
> @@ -14,6 +14,7 @@
>
> #define RSDP_SIGNATURE ACPI_SIGNATURE('R','S','D','P')
> #define RSDT_SIGNATURE ACPI_SIGNATURE('R','S','D','T')
> +#define XSDT_SIGNATURE ACPI_SIGNATURE('X','S','D','T')
> #define FACP_SIGNATURE ACPI_SIGNATURE('F','A','C','P')
> #define FACS_SIGNATURE ACPI_SIGNATURE('F','A','C','S')
>
> @@ -56,6 +57,11 @@ struct acpi_table_rsdt_rev1 {
> u32 table_offset_entry[];
> };
>
> +struct acpi_table_xsdt {
> + ACPI_TABLE_HEADER_DEF
> + u64 table_offset_entry[];
> +};
> +
> struct acpi_table_fadt_rev1 {
> ACPI_TABLE_HEADER_DEF /* ACPI common table header */
> u32 firmware_ctrl; /* Physical address of FACS */
> diff --git a/lib/acpi.c b/lib/acpi.c
> index 166ffd14..d35f09a6 100644
> --- a/lib/acpi.c
> +++ b/lib/acpi.c
> @@ -37,7 +37,8 @@ static struct acpi_table_rsdp *get_rsdp(void)
>
> void *find_acpi_table_addr(u32 sig)
> {
> - struct acpi_table_rsdt_rev1 *rsdt;
> + struct acpi_table_rsdt_rev1 *rsdt = NULL;
> + struct acpi_table_xsdt *xsdt = NULL;
> struct acpi_table_rsdp *rsdp;
> void *end;
> int i;
> @@ -62,18 +63,41 @@ void *find_acpi_table_addr(u32 sig)
> return rsdp;
>
> rsdt = (void *)(ulong) rsdp->rsdt_physical_address;
> - if (!rsdt || rsdt->signature != RSDT_SIGNATURE)
> - return NULL;
> + if (rsdt && rsdt->signature != RSDT_SIGNATURE)
> + rsdt = NULL;
>
> if (sig == RSDT_SIGNATURE)
> return rsdt;
>
> - end = (void *)rsdt + rsdt->length;
> - for (i = 0; (void *)&rsdt->table_offset_entry[i] < end; i++) {
> - struct acpi_table *t = (void *)(ulong) rsdt->table_offset_entry[i];
> + if (rsdp->revision >= 2) {
> + xsdt = (void *)rsdp->xsdt_physical_address;
> + if (xsdt && xsdt->signature != XSDT_SIGNATURE)
> + xsdt = NULL;
> + }
>
> - if (t && t->signature == sig)
> - return t;
> + if (sig == XSDT_SIGNATURE)
> + return xsdt;
> +
> + /*
> + * When the system implements APCI 2.0 and above and XSDT is valid we
> + * have use XSDT to find other ACPI tables, otherwise, we use RSDT.
> + */
> + if (xsdt) {
> + end = (void *)xsdt + xsdt->length;
> + for (i = 0; (void *)&xsdt->table_offset_entry[i] < end; i++) {
> + struct acpi_table *t = (void *)(ulong) xsdt->table_offset_entry[i];
> +
> + if (t && t->signature == sig)
> + return t;
> + }
> + } else if (rsdt) {
> + end = (void *)rsdt + rsdt->length;
> + for (i = 0; (void *)&rsdt->table_offset_entry[i] < end; i++) {
> + struct acpi_table *t = (void *)(ulong) rsdt->table_offset_entry[i];
> +
> + if (t && t->signature == sig)
> + return t;
> + }
> }
>
> return NULL;
--
Shaoqin
^ permalink raw reply [flat|nested] 52+ messages in thread
* [kvm-unit-tests PATCH v5 09/29] lib/acpi: Extend the definition of the FADT table
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
` (7 preceding siblings ...)
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 08/29] lib/acpi: Add support for the XSDT table Nikos Nikoleris
@ 2023-04-28 12:03 ` Nikos Nikoleris
2023-05-01 12:51 ` Shaoqin Huang
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 10/29] devicetree: Check that fdt is not NULL in dt_available() Nikos Nikoleris
` (21 subsequent siblings)
30 siblings, 1 reply; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-28 12:03 UTC (permalink / raw)
To: kvm, kvmarm, andrew.jones
Cc: pbonzini, alexandru.elisei, ricarkol, Andrew Jones
This change add more fields in the APCI table FADT to allow for the
discovery of the PSCI conduit in arm64 systems. The definition for
FADT is similar to the one in include/acpi/actbl.h in Linux.
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Ricardo Koller <ricarkol@google.com>
Reviewed-by: Andrew Jones <drjones@redhat.com>
---
lib/acpi.h | 33 +++++++++++++++++++++++++++++----
lib/acpi.c | 2 +-
x86/s3.c | 2 +-
x86/vmexit.c | 2 +-
4 files changed, 32 insertions(+), 7 deletions(-)
diff --git a/lib/acpi.h b/lib/acpi.h
index 74ba00ac..b714677e 100644
--- a/lib/acpi.h
+++ b/lib/acpi.h
@@ -62,7 +62,15 @@ struct acpi_table_xsdt {
u64 table_offset_entry[];
};
-struct acpi_table_fadt_rev1 {
+struct acpi_generic_address {
+ u8 space_id; /* Address space where struct or register exists */
+ u8 bit_width; /* Size in bits of given register */
+ u8 bit_offset; /* Bit offset within the register */
+ u8 access_width; /* Minimum Access size (ACPI 3.0) */
+ u64 address; /* 64-bit address of struct or register */
+};
+
+struct acpi_table_fadt {
ACPI_TABLE_HEADER_DEF /* ACPI common table header */
u32 firmware_ctrl; /* Physical address of FACS */
u32 dsdt; /* Physical address of DSDT */
@@ -99,9 +107,26 @@ struct acpi_table_fadt_rev1 {
u8 day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */
u8 mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */
u8 century; /* Index to century in RTC CMOS RAM */
- u8 reserved4; /* Reserved */
- u8 reserved4a; /* Reserved */
- u8 reserved4b; /* Reserved */
+ u16 boot_flags; /* IA-PC Boot Architecture Flags (see below for individual flags) */
+ u8 reserved; /* Reserved, must be zero */
+ u32 flags; /* Miscellaneous flag bits (see below for individual flags) */
+ struct acpi_generic_address reset_register; /* 64-bit address of the Reset register */
+ u8 reset_value; /* Value to write to the reset_register port to reset the system */
+ u16 arm_boot_flags; /* ARM-Specific Boot Flags (see below for individual flags) (ACPI 5.1) */
+ u8 minor_revision; /* FADT Minor Revision (ACPI 5.1) */
+ u64 Xfacs; /* 64-bit physical address of FACS */
+ u64 Xdsdt; /* 64-bit physical address of DSDT */
+ struct acpi_generic_address xpm1a_event_block; /* 64-bit Extended Power Mgt 1a Event Reg Blk address */
+ struct acpi_generic_address xpm1b_event_block; /* 64-bit Extended Power Mgt 1b Event Reg Blk address */
+ struct acpi_generic_address xpm1a_control_block; /* 64-bit Extended Power Mgt 1a Control Reg Blk address */
+ struct acpi_generic_address xpm1b_control_block; /* 64-bit Extended Power Mgt 1b Control Reg Blk address */
+ struct acpi_generic_address xpm2_control_block; /* 64-bit Extended Power Mgt 2 Control Reg Blk address */
+ struct acpi_generic_address xpm_timer_block; /* 64-bit Extended Power Mgt Timer Ctrl Reg Blk address */
+ struct acpi_generic_address xgpe0_block; /* 64-bit Extended General Purpose Event 0 Reg Blk address */
+ struct acpi_generic_address xgpe1_block; /* 64-bit Extended General Purpose Event 1 Reg Blk address */
+ struct acpi_generic_address sleep_control; /* 64-bit Sleep Control register (ACPI 5.0) */
+ struct acpi_generic_address sleep_status; /* 64-bit Sleep Status register (ACPI 5.0) */
+ u64 hypervisor_id; /* Hypervisor Vendor ID (ACPI 6.0) */
};
struct acpi_table_facs_rev1 {
diff --git a/lib/acpi.c b/lib/acpi.c
index d35f09a6..a197f3dd 100644
--- a/lib/acpi.c
+++ b/lib/acpi.c
@@ -45,7 +45,7 @@ void *find_acpi_table_addr(u32 sig)
/* FACS is special... */
if (sig == FACS_SIGNATURE) {
- struct acpi_table_fadt_rev1 *fadt;
+ struct acpi_table_fadt *fadt;
fadt = find_acpi_table_addr(FACP_SIGNATURE);
if (!fadt)
diff --git a/x86/s3.c b/x86/s3.c
index 910c57fb..6f2d6d10 100644
--- a/x86/s3.c
+++ b/x86/s3.c
@@ -30,8 +30,8 @@ extern char resume_start, resume_end;
int main(int argc, char **argv)
{
- struct acpi_table_fadt_rev1 *fadt = find_acpi_table_addr(FACP_SIGNATURE);
struct acpi_table_facs_rev1 *facs = find_acpi_table_addr(FACS_SIGNATURE);
+ struct acpi_table_fadt *fadt = find_acpi_table_addr(FACP_SIGNATURE);
char *addr, *resume_vec = (void*)0x1000;
assert(facs);
diff --git a/x86/vmexit.c b/x86/vmexit.c
index 12234f9e..cc086b86 100644
--- a/x86/vmexit.c
+++ b/x86/vmexit.c
@@ -206,7 +206,7 @@ int pm_tmr_blk;
static void inl_pmtimer(void)
{
if (!pm_tmr_blk) {
- struct acpi_table_fadt_rev1 *fadt;
+ struct acpi_table_fadt *fadt;
fadt = find_acpi_table_addr(FACP_SIGNATURE);
pm_tmr_blk = fadt->pm_tmr_blk;
--
2.25.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* Re: [kvm-unit-tests PATCH v5 09/29] lib/acpi: Extend the definition of the FADT table
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 09/29] lib/acpi: Extend the definition of the FADT table Nikos Nikoleris
@ 2023-05-01 12:51 ` Shaoqin Huang
0 siblings, 0 replies; 52+ messages in thread
From: Shaoqin Huang @ 2023-05-01 12:51 UTC (permalink / raw)
To: Nikos Nikoleris, kvm, kvmarm, andrew.jones
Cc: pbonzini, alexandru.elisei, ricarkol, Andrew Jones
On 4/28/23 20:03, Nikos Nikoleris wrote:
> This change add more fields in the APCI table FADT to allow for the
> discovery of the PSCI conduit in arm64 systems. The definition for
> FADT is similar to the one in include/acpi/actbl.h in Linux.
>
> Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
> Reviewed-by: Ricardo Koller <ricarkol@google.com>
> Reviewed-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Shaoqin Huang <shahuang@redhat.com>
> ---
> lib/acpi.h | 33 +++++++++++++++++++++++++++++----
> lib/acpi.c | 2 +-
> x86/s3.c | 2 +-
> x86/vmexit.c | 2 +-
> 4 files changed, 32 insertions(+), 7 deletions(-)
>
> diff --git a/lib/acpi.h b/lib/acpi.h
> index 74ba00ac..b714677e 100644
> --- a/lib/acpi.h
> +++ b/lib/acpi.h
> @@ -62,7 +62,15 @@ struct acpi_table_xsdt {
> u64 table_offset_entry[];
> };
>
> -struct acpi_table_fadt_rev1 {
> +struct acpi_generic_address {
> + u8 space_id; /* Address space where struct or register exists */
> + u8 bit_width; /* Size in bits of given register */
> + u8 bit_offset; /* Bit offset within the register */
> + u8 access_width; /* Minimum Access size (ACPI 3.0) */
> + u64 address; /* 64-bit address of struct or register */
> +};
> +
> +struct acpi_table_fadt {
> ACPI_TABLE_HEADER_DEF /* ACPI common table header */
> u32 firmware_ctrl; /* Physical address of FACS */
> u32 dsdt; /* Physical address of DSDT */
> @@ -99,9 +107,26 @@ struct acpi_table_fadt_rev1 {
> u8 day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */
> u8 mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */
> u8 century; /* Index to century in RTC CMOS RAM */
> - u8 reserved4; /* Reserved */
> - u8 reserved4a; /* Reserved */
> - u8 reserved4b; /* Reserved */
> + u16 boot_flags; /* IA-PC Boot Architecture Flags (see below for individual flags) */
> + u8 reserved; /* Reserved, must be zero */
> + u32 flags; /* Miscellaneous flag bits (see below for individual flags) */
> + struct acpi_generic_address reset_register; /* 64-bit address of the Reset register */
> + u8 reset_value; /* Value to write to the reset_register port to reset the system */
> + u16 arm_boot_flags; /* ARM-Specific Boot Flags (see below for individual flags) (ACPI 5.1) */
> + u8 minor_revision; /* FADT Minor Revision (ACPI 5.1) */
> + u64 Xfacs; /* 64-bit physical address of FACS */
> + u64 Xdsdt; /* 64-bit physical address of DSDT */
> + struct acpi_generic_address xpm1a_event_block; /* 64-bit Extended Power Mgt 1a Event Reg Blk address */
> + struct acpi_generic_address xpm1b_event_block; /* 64-bit Extended Power Mgt 1b Event Reg Blk address */
> + struct acpi_generic_address xpm1a_control_block; /* 64-bit Extended Power Mgt 1a Control Reg Blk address */
> + struct acpi_generic_address xpm1b_control_block; /* 64-bit Extended Power Mgt 1b Control Reg Blk address */
> + struct acpi_generic_address xpm2_control_block; /* 64-bit Extended Power Mgt 2 Control Reg Blk address */
> + struct acpi_generic_address xpm_timer_block; /* 64-bit Extended Power Mgt Timer Ctrl Reg Blk address */
> + struct acpi_generic_address xgpe0_block; /* 64-bit Extended General Purpose Event 0 Reg Blk address */
> + struct acpi_generic_address xgpe1_block; /* 64-bit Extended General Purpose Event 1 Reg Blk address */
> + struct acpi_generic_address sleep_control; /* 64-bit Sleep Control register (ACPI 5.0) */
> + struct acpi_generic_address sleep_status; /* 64-bit Sleep Status register (ACPI 5.0) */
> + u64 hypervisor_id; /* Hypervisor Vendor ID (ACPI 6.0) */
> };
>
> struct acpi_table_facs_rev1 {
> diff --git a/lib/acpi.c b/lib/acpi.c
> index d35f09a6..a197f3dd 100644
> --- a/lib/acpi.c
> +++ b/lib/acpi.c
> @@ -45,7 +45,7 @@ void *find_acpi_table_addr(u32 sig)
>
> /* FACS is special... */
> if (sig == FACS_SIGNATURE) {
> - struct acpi_table_fadt_rev1 *fadt;
> + struct acpi_table_fadt *fadt;
>
> fadt = find_acpi_table_addr(FACP_SIGNATURE);
> if (!fadt)
> diff --git a/x86/s3.c b/x86/s3.c
> index 910c57fb..6f2d6d10 100644
> --- a/x86/s3.c
> +++ b/x86/s3.c
> @@ -30,8 +30,8 @@ extern char resume_start, resume_end;
>
> int main(int argc, char **argv)
> {
> - struct acpi_table_fadt_rev1 *fadt = find_acpi_table_addr(FACP_SIGNATURE);
> struct acpi_table_facs_rev1 *facs = find_acpi_table_addr(FACS_SIGNATURE);
> + struct acpi_table_fadt *fadt = find_acpi_table_addr(FACP_SIGNATURE);
> char *addr, *resume_vec = (void*)0x1000;
>
> assert(facs);
> diff --git a/x86/vmexit.c b/x86/vmexit.c
> index 12234f9e..cc086b86 100644
> --- a/x86/vmexit.c
> +++ b/x86/vmexit.c
> @@ -206,7 +206,7 @@ int pm_tmr_blk;
> static void inl_pmtimer(void)
> {
> if (!pm_tmr_blk) {
> - struct acpi_table_fadt_rev1 *fadt;
> + struct acpi_table_fadt *fadt;
>
> fadt = find_acpi_table_addr(FACP_SIGNATURE);
> pm_tmr_blk = fadt->pm_tmr_blk;
--
Shaoqin
^ permalink raw reply [flat|nested] 52+ messages in thread
* [kvm-unit-tests PATCH v5 10/29] devicetree: Check that fdt is not NULL in dt_available()
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
` (8 preceding siblings ...)
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 09/29] lib/acpi: Extend the definition of the FADT table Nikos Nikoleris
@ 2023-04-28 12:03 ` Nikos Nikoleris
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 11/29] arm64: Add support for setting up the PSCI conduit through ACPI Nikos Nikoleris
` (20 subsequent siblings)
30 siblings, 0 replies; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-28 12:03 UTC (permalink / raw)
To: kvm, kvmarm, andrew.jones; +Cc: pbonzini, alexandru.elisei, ricarkol
Up until now, for platforms that support DT, kvm-unit-tests would
unconditionally use DT to configure the system and the code made the
assumption that the fdt will always be a valid pointer.
On Arm systems that support both ACPI and DT, kvm-unit-tests plans to
follow the same convension as the Linux kernel: attempt to configure the
system using the DT first, then fallback to ACPI.
As a result, the fdt pointer can be NULL. Check for that in dt_available().
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Andrew Jones <andrew.jones@linux.dev>
[ Alex E: Minor changes to the commit message ]
---
lib/devicetree.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/devicetree.c b/lib/devicetree.c
index 78c1f6fb..3ff9d164 100644
--- a/lib/devicetree.c
+++ b/lib/devicetree.c
@@ -16,7 +16,7 @@ const void *dt_fdt(void)
bool dt_available(void)
{
- return fdt_check_header(fdt) == 0;
+ return fdt && fdt_check_header(fdt) == 0;
}
int dt_get_nr_cells(int fdtnode, u32 *nr_address_cells, u32 *nr_size_cells)
--
2.25.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [kvm-unit-tests PATCH v5 11/29] arm64: Add support for setting up the PSCI conduit through ACPI
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
` (9 preceding siblings ...)
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 10/29] devicetree: Check that fdt is not NULL in dt_available() Nikos Nikoleris
@ 2023-04-28 12:03 ` Nikos Nikoleris
2023-05-01 12:54 ` Shaoqin Huang
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 12/29] arm64: Add support for discovering the UART " Nikos Nikoleris
` (19 subsequent siblings)
30 siblings, 1 reply; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-28 12:03 UTC (permalink / raw)
To: kvm, kvmarm, andrew.jones
Cc: pbonzini, alexandru.elisei, ricarkol, Andrew Jones
In systems with ACPI support and when a DT is not provided, we can use
the FADT to discover whether PSCI calls need to use smc or hvc
calls. This change implements this but retains the default behavior;
we check if a valid DT is provided, if not, we try to setup the PSCI
conduit using ACPI.
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Ricardo Koller <ricarkol@google.com>
---
arm/Makefile.arm64 | 4 ++++
lib/acpi.h | 5 +++++
lib/arm/psci.c | 37 ++++++++++++++++++++++++++++++++++++-
3 files changed, 45 insertions(+), 1 deletion(-)
diff --git a/arm/Makefile.arm64 b/arm/Makefile.arm64
index 42e18e77..6dff6cad 100644
--- a/arm/Makefile.arm64
+++ b/arm/Makefile.arm64
@@ -25,6 +25,10 @@ cflatobjs += lib/arm64/processor.o
cflatobjs += lib/arm64/spinlock.o
cflatobjs += lib/arm64/gic-v3-its.o lib/arm64/gic-v3-its-cmd.o
+ifeq ($(CONFIG_EFI),y)
+cflatobjs += lib/acpi.o
+endif
+
OBJDIRS += lib/arm64
# arm64 specific tests
diff --git a/lib/acpi.h b/lib/acpi.h
index b714677e..ef4a8e1d 100644
--- a/lib/acpi.h
+++ b/lib/acpi.h
@@ -129,6 +129,11 @@ struct acpi_table_fadt {
u64 hypervisor_id; /* Hypervisor Vendor ID (ACPI 6.0) */
};
+/* Masks for FADT ARM Boot Architecture Flags (arm_boot_flags) ACPI 5.1 */
+
+#define ACPI_FADT_PSCI_COMPLIANT (1) /* 00: [V5+] PSCI 0.2+ is implemented */
+#define ACPI_FADT_PSCI_USE_HVC (1<<1) /* 01: [V5+] HVC must be used instead of SMC as the PSCI conduit */
+
struct acpi_table_facs_rev1 {
u32 signature; /* ACPI Signature */
u32 length; /* Length of structure, in bytes */
diff --git a/lib/arm/psci.c b/lib/arm/psci.c
index 9c031a12..bddb0787 100644
--- a/lib/arm/psci.c
+++ b/lib/arm/psci.c
@@ -56,7 +56,7 @@ void psci_system_off(void)
printf("CPU%d unable to do system off (error = %d)\n", smp_processor_id(), err);
}
-void psci_set_conduit(void)
+static void psci_set_conduit_fdt(void)
{
const void *fdt = dt_fdt();
const struct fdt_property *method;
@@ -75,3 +75,38 @@ void psci_set_conduit(void)
else
assert_msg(false, "Unknown PSCI conduit: %s", method->data);
}
+
+#ifdef CONFIG_EFI
+
+#include <acpi.h>
+
+static void psci_set_conduit_acpi(void)
+{
+ struct acpi_table_fadt *fadt = find_acpi_table_addr(FACP_SIGNATURE);
+
+ assert_msg(fadt, "Unable to find ACPI FADT");
+ assert_msg(fadt->arm_boot_flags & ACPI_FADT_PSCI_COMPLIANT,
+ "PSCI is not supported in this platform");
+
+ if (fadt->arm_boot_flags & ACPI_FADT_PSCI_USE_HVC)
+ psci_invoke = psci_invoke_hvc;
+ else
+ psci_invoke = psci_invoke_smc;
+}
+
+#else
+
+static void psci_set_conduit_acpi(void)
+{
+ assert_msg(false, "ACPI not available");
+}
+
+#endif
+
+void psci_set_conduit(void)
+{
+ if (dt_available())
+ psci_set_conduit_fdt();
+ else
+ psci_set_conduit_acpi();
+}
--
2.25.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* Re: [kvm-unit-tests PATCH v5 11/29] arm64: Add support for setting up the PSCI conduit through ACPI
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 11/29] arm64: Add support for setting up the PSCI conduit through ACPI Nikos Nikoleris
@ 2023-05-01 12:54 ` Shaoqin Huang
0 siblings, 0 replies; 52+ messages in thread
From: Shaoqin Huang @ 2023-05-01 12:54 UTC (permalink / raw)
To: Nikos Nikoleris, kvm, kvmarm, andrew.jones
Cc: pbonzini, alexandru.elisei, ricarkol, Andrew Jones
On 4/28/23 20:03, Nikos Nikoleris wrote:
> In systems with ACPI support and when a DT is not provided, we can use
> the FADT to discover whether PSCI calls need to use smc or hvc
> calls. This change implements this but retains the default behavior;
> we check if a valid DT is provided, if not, we try to setup the PSCI
> conduit using ACPI.
>
> Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
> Reviewed-by: Andrew Jones <drjones@redhat.com>
> Reviewed-by: Ricardo Koller <ricarkol@google.com>
Reviewed-by: Shaoqin Huang <shahuang@redhat.com>
> ---
> arm/Makefile.arm64 | 4 ++++
> lib/acpi.h | 5 +++++
> lib/arm/psci.c | 37 ++++++++++++++++++++++++++++++++++++-
> 3 files changed, 45 insertions(+), 1 deletion(-)
>
> diff --git a/arm/Makefile.arm64 b/arm/Makefile.arm64
> index 42e18e77..6dff6cad 100644
> --- a/arm/Makefile.arm64
> +++ b/arm/Makefile.arm64
> @@ -25,6 +25,10 @@ cflatobjs += lib/arm64/processor.o
> cflatobjs += lib/arm64/spinlock.o
> cflatobjs += lib/arm64/gic-v3-its.o lib/arm64/gic-v3-its-cmd.o
>
> +ifeq ($(CONFIG_EFI),y)
> +cflatobjs += lib/acpi.o
> +endif
> +
> OBJDIRS += lib/arm64
>
> # arm64 specific tests
> diff --git a/lib/acpi.h b/lib/acpi.h
> index b714677e..ef4a8e1d 100644
> --- a/lib/acpi.h
> +++ b/lib/acpi.h
> @@ -129,6 +129,11 @@ struct acpi_table_fadt {
> u64 hypervisor_id; /* Hypervisor Vendor ID (ACPI 6.0) */
> };
>
> +/* Masks for FADT ARM Boot Architecture Flags (arm_boot_flags) ACPI 5.1 */
> +
> +#define ACPI_FADT_PSCI_COMPLIANT (1) /* 00: [V5+] PSCI 0.2+ is implemented */
> +#define ACPI_FADT_PSCI_USE_HVC (1<<1) /* 01: [V5+] HVC must be used instead of SMC as the PSCI conduit */
> +
> struct acpi_table_facs_rev1 {
> u32 signature; /* ACPI Signature */
> u32 length; /* Length of structure, in bytes */
> diff --git a/lib/arm/psci.c b/lib/arm/psci.c
> index 9c031a12..bddb0787 100644
> --- a/lib/arm/psci.c
> +++ b/lib/arm/psci.c
> @@ -56,7 +56,7 @@ void psci_system_off(void)
> printf("CPU%d unable to do system off (error = %d)\n", smp_processor_id(), err);
> }
>
> -void psci_set_conduit(void)
> +static void psci_set_conduit_fdt(void)
> {
> const void *fdt = dt_fdt();
> const struct fdt_property *method;
> @@ -75,3 +75,38 @@ void psci_set_conduit(void)
> else
> assert_msg(false, "Unknown PSCI conduit: %s", method->data);
> }
> +
> +#ifdef CONFIG_EFI
> +
> +#include <acpi.h>
> +
> +static void psci_set_conduit_acpi(void)
> +{
> + struct acpi_table_fadt *fadt = find_acpi_table_addr(FACP_SIGNATURE);
> +
> + assert_msg(fadt, "Unable to find ACPI FADT");
> + assert_msg(fadt->arm_boot_flags & ACPI_FADT_PSCI_COMPLIANT,
> + "PSCI is not supported in this platform");
> +
> + if (fadt->arm_boot_flags & ACPI_FADT_PSCI_USE_HVC)
> + psci_invoke = psci_invoke_hvc;
> + else
> + psci_invoke = psci_invoke_smc;
> +}
> +
> +#else
> +
> +static void psci_set_conduit_acpi(void)
> +{
> + assert_msg(false, "ACPI not available");
> +}
> +
> +#endif
> +
> +void psci_set_conduit(void)
> +{
> + if (dt_available())
> + psci_set_conduit_fdt();
> + else
> + psci_set_conduit_acpi();
> +}
--
Shaoqin
^ permalink raw reply [flat|nested] 52+ messages in thread
* [kvm-unit-tests PATCH v5 12/29] arm64: Add support for discovering the UART through ACPI
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
` (10 preceding siblings ...)
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 11/29] arm64: Add support for setting up the PSCI conduit through ACPI Nikos Nikoleris
@ 2023-04-28 12:03 ` Nikos Nikoleris
2023-05-01 12:55 ` Shaoqin Huang
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 13/29] arm64: Add support for timer initialization " Nikos Nikoleris
` (18 subsequent siblings)
30 siblings, 1 reply; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-28 12:03 UTC (permalink / raw)
To: kvm, kvmarm, andrew.jones
Cc: pbonzini, alexandru.elisei, ricarkol, Andrew Jones
In systems with ACPI support and when a DT is not provided, we can use
the SPCR to discover the serial port address range. This change
implements this but retains the default behavior; we check if a valid
DT is provided, if not, we try to discover the UART using ACPI.
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Ricardo Koller <ricarkol@google.com>
---
lib/acpi.h | 25 +++++++++++++++++++++++++
lib/arm/io.c | 34 +++++++++++++++++++++++++++++-----
2 files changed, 54 insertions(+), 5 deletions(-)
diff --git a/lib/acpi.h b/lib/acpi.h
index ef4a8e1d..54ed9ef7 100644
--- a/lib/acpi.h
+++ b/lib/acpi.h
@@ -17,6 +17,7 @@
#define XSDT_SIGNATURE ACPI_SIGNATURE('X','S','D','T')
#define FACP_SIGNATURE ACPI_SIGNATURE('F','A','C','P')
#define FACS_SIGNATURE ACPI_SIGNATURE('F','A','C','S')
+#define SPCR_SIGNATURE ACPI_SIGNATURE('S','P','C','R')
#define ACPI_SIGNATURE_8BYTE(c1, c2, c3, c4, c5, c6, c7, c8) \
(((uint64_t)(ACPI_SIGNATURE(c1, c2, c3, c4))) | \
@@ -145,6 +146,30 @@ struct acpi_table_facs_rev1 {
u8 reserved3[40]; /* Reserved - must be zero */
};
+struct spcr_descriptor {
+ ACPI_TABLE_HEADER_DEF /* ACPI common table header */
+ u8 interface_type; /* 0=full 16550, 1=subset of 16550 */
+ u8 reserved[3];
+ struct acpi_generic_address serial_port;
+ u8 interrupt_type;
+ u8 pc_interrupt;
+ u32 interrupt;
+ u8 baud_rate;
+ u8 parity;
+ u8 stop_bits;
+ u8 flow_control;
+ u8 terminal_type;
+ u8 reserved1;
+ u16 pci_device_id;
+ u16 pci_vendor_id;
+ u8 pci_bus;
+ u8 pci_device;
+ u8 pci_function;
+ u32 pci_flags;
+ u8 pci_segment;
+ u32 reserved2;
+};
+
#pragma pack(0)
void set_efi_rsdp(struct acpi_table_rsdp *rsdp);
diff --git a/lib/arm/io.c b/lib/arm/io.c
index 343e1082..19f93490 100644
--- a/lib/arm/io.c
+++ b/lib/arm/io.c
@@ -29,7 +29,7 @@ static struct spinlock uart_lock;
#define UART_EARLY_BASE (u8 *)(unsigned long)CONFIG_UART_EARLY_BASE
static volatile u8 *uart0_base = UART_EARLY_BASE;
-static void uart0_init(void)
+static void uart0_init_fdt(void)
{
/*
* kvm-unit-tests uses the uart only for output. Both uart models have
@@ -65,17 +65,41 @@ static void uart0_init(void)
}
uart0_base = ioremap(base.addr, base.size);
+}
+
+#ifdef CONFIG_EFI
+
+#include <acpi.h>
+
+static void uart0_init_acpi(void)
+{
+ struct spcr_descriptor *spcr = find_acpi_table_addr(SPCR_SIGNATURE);
+
+ assert_msg(spcr, "Unable to find ACPI SPCR");
+ uart0_base = ioremap(spcr->serial_port.address, spcr->serial_port.bit_width);
+}
+#else
+
+static void uart0_init_acpi(void)
+{
+ assert_msg(false, "ACPI not available");
+}
+
+#endif
+
+void io_init(void)
+{
+ if (dt_available())
+ uart0_init_fdt();
+ else
+ uart0_init_acpi();
if (uart0_base != UART_EARLY_BASE) {
printf("WARNING: early print support may not work. "
"Found uart at %p, but early base is %p.\n",
uart0_base, UART_EARLY_BASE);
}
-}
-void io_init(void)
-{
- uart0_init();
chr_testdev_init();
}
--
2.25.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* Re: [kvm-unit-tests PATCH v5 12/29] arm64: Add support for discovering the UART through ACPI
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 12/29] arm64: Add support for discovering the UART " Nikos Nikoleris
@ 2023-05-01 12:55 ` Shaoqin Huang
0 siblings, 0 replies; 52+ messages in thread
From: Shaoqin Huang @ 2023-05-01 12:55 UTC (permalink / raw)
To: Nikos Nikoleris, kvm, kvmarm, andrew.jones
Cc: pbonzini, alexandru.elisei, ricarkol
On 4/28/23 20:03, Nikos Nikoleris wrote:
> In systems with ACPI support and when a DT is not provided, we can use
> the SPCR to discover the serial port address range. This change
> implements this but retains the default behavior; we check if a valid
> DT is provided, if not, we try to discover the UART using ACPI.
>
> Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
> Reviewed-by: Andrew Jones <drjones@redhat.com>
> Reviewed-by: Ricardo Koller <ricarkol@google.com>
Reviewed-by: Shaoqin Huang <shahuang@redhat.com>
> ---
> lib/acpi.h | 25 +++++++++++++++++++++++++
> lib/arm/io.c | 34 +++++++++++++++++++++++++++++-----
> 2 files changed, 54 insertions(+), 5 deletions(-)
>
> diff --git a/lib/acpi.h b/lib/acpi.h
> index ef4a8e1d..54ed9ef7 100644
> --- a/lib/acpi.h
> +++ b/lib/acpi.h
> @@ -17,6 +17,7 @@
> #define XSDT_SIGNATURE ACPI_SIGNATURE('X','S','D','T')
> #define FACP_SIGNATURE ACPI_SIGNATURE('F','A','C','P')
> #define FACS_SIGNATURE ACPI_SIGNATURE('F','A','C','S')
> +#define SPCR_SIGNATURE ACPI_SIGNATURE('S','P','C','R')
>
> #define ACPI_SIGNATURE_8BYTE(c1, c2, c3, c4, c5, c6, c7, c8) \
> (((uint64_t)(ACPI_SIGNATURE(c1, c2, c3, c4))) | \
> @@ -145,6 +146,30 @@ struct acpi_table_facs_rev1 {
> u8 reserved3[40]; /* Reserved - must be zero */
> };
>
> +struct spcr_descriptor {
> + ACPI_TABLE_HEADER_DEF /* ACPI common table header */
> + u8 interface_type; /* 0=full 16550, 1=subset of 16550 */
> + u8 reserved[3];
> + struct acpi_generic_address serial_port;
> + u8 interrupt_type;
> + u8 pc_interrupt;
> + u32 interrupt;
> + u8 baud_rate;
> + u8 parity;
> + u8 stop_bits;
> + u8 flow_control;
> + u8 terminal_type;
> + u8 reserved1;
> + u16 pci_device_id;
> + u16 pci_vendor_id;
> + u8 pci_bus;
> + u8 pci_device;
> + u8 pci_function;
> + u32 pci_flags;
> + u8 pci_segment;
> + u32 reserved2;
> +};
> +
> #pragma pack(0)
>
> void set_efi_rsdp(struct acpi_table_rsdp *rsdp);
> diff --git a/lib/arm/io.c b/lib/arm/io.c
> index 343e1082..19f93490 100644
> --- a/lib/arm/io.c
> +++ b/lib/arm/io.c
> @@ -29,7 +29,7 @@ static struct spinlock uart_lock;
> #define UART_EARLY_BASE (u8 *)(unsigned long)CONFIG_UART_EARLY_BASE
> static volatile u8 *uart0_base = UART_EARLY_BASE;
>
> -static void uart0_init(void)
> +static void uart0_init_fdt(void)
> {
> /*
> * kvm-unit-tests uses the uart only for output. Both uart models have
> @@ -65,17 +65,41 @@ static void uart0_init(void)
> }
>
> uart0_base = ioremap(base.addr, base.size);
> +}
> +
> +#ifdef CONFIG_EFI
> +
> +#include <acpi.h>
> +
> +static void uart0_init_acpi(void)
> +{
> + struct spcr_descriptor *spcr = find_acpi_table_addr(SPCR_SIGNATURE);
> +
> + assert_msg(spcr, "Unable to find ACPI SPCR");
> + uart0_base = ioremap(spcr->serial_port.address, spcr->serial_port.bit_width);
> +}
> +#else
> +
> +static void uart0_init_acpi(void)
> +{
> + assert_msg(false, "ACPI not available");
> +}
> +
> +#endif
> +
> +void io_init(void)
> +{
> + if (dt_available())
> + uart0_init_fdt();
> + else
> + uart0_init_acpi();
>
> if (uart0_base != UART_EARLY_BASE) {
> printf("WARNING: early print support may not work. "
> "Found uart at %p, but early base is %p.\n",
> uart0_base, UART_EARLY_BASE);
> }
> -}
>
> -void io_init(void)
> -{
> - uart0_init();
> chr_testdev_init();
> }
>
--
Shaoqin
^ permalink raw reply [flat|nested] 52+ messages in thread
* [kvm-unit-tests PATCH v5 13/29] arm64: Add support for timer initialization through ACPI
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
` (11 preceding siblings ...)
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 12/29] arm64: Add support for discovering the UART " Nikos Nikoleris
@ 2023-04-28 12:03 ` Nikos Nikoleris
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 14/29] arm64: Add support for cpu " Nikos Nikoleris
` (17 subsequent siblings)
30 siblings, 0 replies; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-28 12:03 UTC (permalink / raw)
To: kvm, kvmarm, andrew.jones
Cc: pbonzini, alexandru.elisei, ricarkol, Andrew Jones
For systems with ACPI support, we can discover timers through the ACPI
GTDT table. This change implements the code to discover timers through
the GTDT and adds ACPI support in timer_save_state. This change
retains the default behavior; we check if a valid DT is provided, if
not, we try to discover timers using ACPI.
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Andrew Jones <drjones@redhat.com>
---
arm/Makefile.common | 1 +
lib/arm/asm/timer.h | 2 +
lib/acpi.h | 18 +++++++++
lib/arm/setup.c | 39 -------------------
lib/arm/timer.c | 92 +++++++++++++++++++++++++++++++++++++++++++++
arm/micro-bench.c | 4 +-
arm/timer.c | 10 ++---
7 files changed, 120 insertions(+), 46 deletions(-)
create mode 100644 lib/arm/timer.c
diff --git a/arm/Makefile.common b/arm/Makefile.common
index 1bbec64f..647b0fb1 100644
--- a/arm/Makefile.common
+++ b/arm/Makefile.common
@@ -53,6 +53,7 @@ cflatobjs += lib/arm/psci.o
cflatobjs += lib/arm/smp.o
cflatobjs += lib/arm/delay.o
cflatobjs += lib/arm/gic.o lib/arm/gic-v2.o lib/arm/gic-v3.o
+cflatobjs += lib/arm/timer.o
OBJDIRS += lib/arm
diff --git a/lib/arm/asm/timer.h b/lib/arm/asm/timer.h
index f75cc67f..aaf839fc 100644
--- a/lib/arm/asm/timer.h
+++ b/lib/arm/asm/timer.h
@@ -27,5 +27,7 @@ extern struct timer_state __timer_state;
#define TIMER_PTIMER_IRQ (__timer_state.ptimer.irq)
#define TIMER_VTIMER_IRQ (__timer_state.vtimer.irq)
+void timer_save_state(void);
+
#endif /* !__ASSEMBLY__ */
#endif /* _ASMARM_TIMER_H_ */
diff --git a/lib/acpi.h b/lib/acpi.h
index 54ed9ef7..04e4d1c3 100644
--- a/lib/acpi.h
+++ b/lib/acpi.h
@@ -18,6 +18,7 @@
#define FACP_SIGNATURE ACPI_SIGNATURE('F','A','C','P')
#define FACS_SIGNATURE ACPI_SIGNATURE('F','A','C','S')
#define SPCR_SIGNATURE ACPI_SIGNATURE('S','P','C','R')
+#define GTDT_SIGNATURE ACPI_SIGNATURE('G','T','D','T')
#define ACPI_SIGNATURE_8BYTE(c1, c2, c3, c4, c5, c6, c7, c8) \
(((uint64_t)(ACPI_SIGNATURE(c1, c2, c3, c4))) | \
@@ -170,6 +171,23 @@ struct spcr_descriptor {
u32 reserved2;
};
+struct acpi_table_gtdt {
+ ACPI_TABLE_HEADER_DEF /* ACPI common table header */
+ u64 counter_block_addresss;
+ u32 reserved;
+ u32 secure_el1_interrupt;
+ u32 secure_el1_flags;
+ u32 non_secure_el1_interrupt;
+ u32 non_secure_el1_flags;
+ u32 virtual_timer_interrupt;
+ u32 virtual_timer_flags;
+ u32 non_secure_el2_interrupt;
+ u32 non_secure_el2_flags;
+ u64 counter_read_block_address;
+ u32 platform_timer_count;
+ u32 platform_timer_offset;
+};
+
#pragma pack(0)
void set_efi_rsdp(struct acpi_table_rsdp *rsdp);
diff --git a/lib/arm/setup.c b/lib/arm/setup.c
index bcdf0d78..1572c64e 100644
--- a/lib/arm/setup.c
+++ b/lib/arm/setup.c
@@ -35,8 +35,6 @@
extern unsigned long etext;
-struct timer_state __timer_state;
-
char *initrd;
u32 initrd_size;
@@ -199,43 +197,6 @@ static void mem_init(phys_addr_t freemem_start)
page_alloc_ops_enable();
}
-static void timer_save_state(void)
-{
- const struct fdt_property *prop;
- const void *fdt = dt_fdt();
- int node, len;
- u32 *data;
-
- node = fdt_node_offset_by_compatible(fdt, -1, "arm,armv8-timer");
- assert(node >= 0 || node == -FDT_ERR_NOTFOUND);
-
- if (node == -FDT_ERR_NOTFOUND) {
- __timer_state.ptimer.irq = -1;
- __timer_state.vtimer.irq = -1;
- return;
- }
-
- /*
- * From Linux devicetree timer binding documentation
- *
- * interrupts <type irq flags>:
- * secure timer irq
- * non-secure timer irq (ptimer)
- * virtual timer irq (vtimer)
- * hypervisor timer irq
- */
- prop = fdt_get_property(fdt, node, "interrupts", &len);
- assert(prop && len == (4 * 3 * sizeof(u32)));
-
- data = (u32 *)prop->data;
- assert(fdt32_to_cpu(data[3]) == 1 /* PPI */);
- __timer_state.ptimer.irq = fdt32_to_cpu(data[4]);
- __timer_state.ptimer.irq_flags = fdt32_to_cpu(data[5]);
- assert(fdt32_to_cpu(data[6]) == 1 /* PPI */);
- __timer_state.vtimer.irq = fdt32_to_cpu(data[7]);
- __timer_state.vtimer.irq_flags = fdt32_to_cpu(data[8]);
-}
-
void setup(const void *fdt, phys_addr_t freemem_start)
{
void *freemem;
diff --git a/lib/arm/timer.c b/lib/arm/timer.c
new file mode 100644
index 00000000..ae702e41
--- /dev/null
+++ b/lib/arm/timer.c
@@ -0,0 +1,92 @@
+/*
+ * Initialize timers.
+ *
+ * Copyright (C) 2022, Arm Ltd., Nikos Nikoleris <nikos.nikoleris@arm.com>
+ * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#include <libcflat.h>
+#include <acpi.h>
+#include <devicetree.h>
+#include <libfdt/libfdt.h>
+#include <asm/gic.h>
+#include <asm/timer.h>
+
+struct timer_state __timer_state;
+
+static void timer_save_state_fdt(void)
+{
+ const struct fdt_property *prop;
+ const void *fdt = dt_fdt();
+ int node, len;
+ u32 *data;
+
+ node = fdt_node_offset_by_compatible(fdt, -1, "arm,armv8-timer");
+ assert(node >= 0 || node == -FDT_ERR_NOTFOUND);
+
+ if (node == -FDT_ERR_NOTFOUND) {
+ __timer_state.ptimer.irq = -1;
+ __timer_state.vtimer.irq = -1;
+ return;
+ }
+
+ /*
+ * From Linux devicetree timer binding documentation
+ *
+ * interrupts <type irq flags>:
+ * secure timer irq
+ * non-secure timer irq (ptimer)
+ * virtual timer irq (vtimer)
+ * hypervisor timer irq
+ */
+ prop = fdt_get_property(fdt, node, "interrupts", &len);
+ assert(prop && len == (4 * 3 * sizeof(u32)));
+
+ data = (u32 *) prop->data;
+ assert(fdt32_to_cpu(data[3]) == 1 /* PPI */ );
+ __timer_state.ptimer.irq = PPI(fdt32_to_cpu(data[4]));
+ __timer_state.ptimer.irq_flags = fdt32_to_cpu(data[5]);
+ assert(fdt32_to_cpu(data[6]) == 1 /* PPI */ );
+ __timer_state.vtimer.irq = PPI(fdt32_to_cpu(data[7]));
+ __timer_state.vtimer.irq_flags = fdt32_to_cpu(data[8]);
+}
+
+#ifdef CONFIG_EFI
+
+#include <acpi.h>
+
+static void timer_save_state_acpi(void)
+{
+ struct acpi_table_gtdt *gtdt = find_acpi_table_addr(GTDT_SIGNATURE);
+
+ if (!gtdt) {
+ printf("Cannot find ACPI GTDT");
+ __timer_state.ptimer.irq = -1;
+ __timer_state.vtimer.irq = -1;
+ return;
+ }
+
+ __timer_state.ptimer.irq = gtdt->non_secure_el1_interrupt;
+ __timer_state.ptimer.irq_flags = gtdt->non_secure_el1_flags;
+
+ __timer_state.vtimer.irq = gtdt->virtual_timer_interrupt;
+ __timer_state.vtimer.irq_flags = gtdt->virtual_timer_flags;
+}
+
+#else
+
+static void timer_save_state_acpi(void)
+{
+ assert_msg(false, "ACPI not available");
+}
+
+#endif
+
+void timer_save_state(void)
+{
+ if (dt_available())
+ timer_save_state_fdt();
+ else
+ timer_save_state_acpi();
+}
diff --git a/arm/micro-bench.c b/arm/micro-bench.c
index 090fda6a..bfd181dc 100644
--- a/arm/micro-bench.c
+++ b/arm/micro-bench.c
@@ -43,7 +43,7 @@ static void gic_irq_handler(struct pt_regs *regs)
irq_received = true;
gic_write_eoir(irqstat);
- if (irqstat == PPI(TIMER_VTIMER_IRQ)) {
+ if (irqstat == TIMER_VTIMER_IRQ) {
write_sysreg((ARCH_TIMER_CTL_IMASK | ARCH_TIMER_CTL_ENABLE),
cntv_ctl_el0);
isb();
@@ -216,7 +216,7 @@ static bool timer_prep(void)
install_irq_handler(EL1H_IRQ, gic_irq_handler);
local_irq_enable();
- gic_enable_irq(PPI(TIMER_VTIMER_IRQ));
+ gic_enable_irq(TIMER_VTIMER_IRQ);
write_sysreg(ARCH_TIMER_CTL_IMASK | ARCH_TIMER_CTL_ENABLE, cntv_ctl_el0);
isb();
diff --git a/arm/timer.c b/arm/timer.c
index c0a8388a..2cb80518 100644
--- a/arm/timer.c
+++ b/arm/timer.c
@@ -136,7 +136,7 @@ static struct timer_info ptimer_info = {
static void set_timer_irq_enabled(struct timer_info *info, bool enabled)
{
- u32 irq = PPI(info->irq);
+ u32 irq = info->irq;
if (enabled)
gic_enable_irq(irq);
@@ -150,9 +150,9 @@ static void irq_handler(struct pt_regs *regs)
u32 irqstat = gic_read_iar();
u32 irqnr = gic_iar_irqnr(irqstat);
- if (irqnr == PPI(vtimer_info.irq)) {
+ if (irqnr == vtimer_info.irq) {
info = &vtimer_info;
- } else if (irqnr == PPI(ptimer_info.irq)) {
+ } else if (irqnr == ptimer_info.irq) {
info = &ptimer_info;
} else {
if (irqnr != GICC_INT_SPURIOUS)
@@ -182,9 +182,9 @@ static bool gic_timer_check_state(struct timer_info *info,
/* Wait for up to 1s for the GIC to sample the interrupt. */
for (i = 0; i < 10; i++) {
mdelay(100);
- if (gic_irq_state(PPI(info->irq)) == expected_state) {
+ if (gic_irq_state(info->irq) == expected_state) {
mdelay(100);
- if (gic_irq_state(PPI(info->irq)) == expected_state)
+ if (gic_irq_state(info->irq) == expected_state)
return true;
}
}
--
2.25.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [kvm-unit-tests PATCH v5 14/29] arm64: Add support for cpu initialization through ACPI
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
` (12 preceding siblings ...)
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 13/29] arm64: Add support for timer initialization " Nikos Nikoleris
@ 2023-04-28 12:03 ` Nikos Nikoleris
2023-05-01 12:56 ` Shaoqin Huang
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 15/29] arm64: Add support for gic " Nikos Nikoleris
` (16 subsequent siblings)
30 siblings, 1 reply; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-28 12:03 UTC (permalink / raw)
To: kvm, kvmarm, andrew.jones
Cc: pbonzini, alexandru.elisei, ricarkol, Andrew Jones
In systems with ACPI support and when a DT is not provided, we can use
the MADTs to discover the number of CPUs and their corresponding MIDR.
This change implements this but retains the default behavior; we check
if a valid DT is provided, if not, we try to discover the cores in the
system using ACPI.
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Andrew Jones <drjones@redhat.com>
---
lib/acpi.h | 63 +++++++++++++++++++++++++++++++++++++++++++++++++
lib/acpi.c | 20 ++++++++++++++++
lib/arm/setup.c | 42 ++++++++++++++++++++++++++++++---
3 files changed, 122 insertions(+), 3 deletions(-)
diff --git a/lib/acpi.h b/lib/acpi.h
index 04e4d1c3..4a59f543 100644
--- a/lib/acpi.h
+++ b/lib/acpi.h
@@ -17,6 +17,7 @@
#define XSDT_SIGNATURE ACPI_SIGNATURE('X','S','D','T')
#define FACP_SIGNATURE ACPI_SIGNATURE('F','A','C','P')
#define FACS_SIGNATURE ACPI_SIGNATURE('F','A','C','S')
+#define MADT_SIGNATURE ACPI_SIGNATURE('A','P','I','C')
#define SPCR_SIGNATURE ACPI_SIGNATURE('S','P','C','R')
#define GTDT_SIGNATURE ACPI_SIGNATURE('G','T','D','T')
@@ -147,6 +148,67 @@ struct acpi_table_facs_rev1 {
u8 reserved3[40]; /* Reserved - must be zero */
};
+struct acpi_table_madt {
+ ACPI_TABLE_HEADER_DEF /* ACPI common table header */
+ u32 address; /* Physical address of local APIC */
+ u32 flags;
+};
+
+struct acpi_subtable_header {
+ u8 type;
+ u8 length;
+};
+
+typedef int (*acpi_table_handler)(struct acpi_subtable_header *header);
+
+/* 11: Generic interrupt - GICC (ACPI 5.0 + ACPI 6.0 + ACPI 6.3 changes) */
+
+struct acpi_madt_generic_interrupt {
+ u8 type;
+ u8 length;
+ u16 reserved; /* reserved - must be zero */
+ u32 cpu_interface_number;
+ u32 uid;
+ u32 flags;
+ u32 parking_version;
+ u32 performance_interrupt;
+ u64 parked_address;
+ u64 base_address;
+ u64 gicv_base_address;
+ u64 gich_base_address;
+ u32 vgic_interrupt;
+ u64 gicr_base_address;
+ u64 arm_mpidr;
+ u8 efficiency_class;
+ u8 reserved2[1];
+ u16 spe_interrupt; /* ACPI 6.3 */
+};
+
+/* Values for MADT subtable type in struct acpi_subtable_header */
+
+enum acpi_madt_type {
+ ACPI_MADT_TYPE_LOCAL_APIC = 0,
+ ACPI_MADT_TYPE_IO_APIC = 1,
+ ACPI_MADT_TYPE_INTERRUPT_OVERRIDE = 2,
+ ACPI_MADT_TYPE_NMI_SOURCE = 3,
+ ACPI_MADT_TYPE_LOCAL_APIC_NMI = 4,
+ ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE = 5,
+ ACPI_MADT_TYPE_IO_SAPIC = 6,
+ ACPI_MADT_TYPE_LOCAL_SAPIC = 7,
+ ACPI_MADT_TYPE_INTERRUPT_SOURCE = 8,
+ ACPI_MADT_TYPE_LOCAL_X2APIC = 9,
+ ACPI_MADT_TYPE_LOCAL_X2APIC_NMI = 10,
+ ACPI_MADT_TYPE_GENERIC_INTERRUPT = 11,
+ ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR = 12,
+ ACPI_MADT_TYPE_GENERIC_MSI_FRAME = 13,
+ ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR = 14,
+ ACPI_MADT_TYPE_GENERIC_TRANSLATOR = 15,
+ ACPI_MADT_TYPE_RESERVED = 16 /* 16 and greater are reserved */
+};
+
+/* MADT Local APIC flags */
+#define ACPI_MADT_ENABLED (1) /* 00: Processor is usable if set */
+
struct spcr_descriptor {
ACPI_TABLE_HEADER_DEF /* ACPI common table header */
u8 interface_type; /* 0=full 16550, 1=subset of 16550 */
@@ -192,5 +254,6 @@ struct acpi_table_gtdt {
void set_efi_rsdp(struct acpi_table_rsdp *rsdp);
void *find_acpi_table_addr(u32 sig);
+void acpi_table_parse_madt(enum acpi_madt_type mtype, acpi_table_handler handler);
#endif
diff --git a/lib/acpi.c b/lib/acpi.c
index a197f3dd..bbe33d08 100644
--- a/lib/acpi.c
+++ b/lib/acpi.c
@@ -102,3 +102,23 @@ void *find_acpi_table_addr(u32 sig)
return NULL;
}
+
+void acpi_table_parse_madt(enum acpi_madt_type mtype, acpi_table_handler handler)
+{
+ struct acpi_table_madt *madt;
+ struct acpi_subtable_header *header;
+ void *end;
+
+ madt = find_acpi_table_addr(MADT_SIGNATURE);
+ assert(madt);
+
+ header = (void *)(ulong) madt + sizeof(struct acpi_table_madt);
+ end = (void *)((ulong) madt + madt->length);
+
+ while ((void *)header < end) {
+ if (header->type == mtype)
+ handler(header);
+
+ header = (void *)(ulong) header + header->length;
+ }
+}
diff --git a/lib/arm/setup.c b/lib/arm/setup.c
index 1572c64e..59b0aedd 100644
--- a/lib/arm/setup.c
+++ b/lib/arm/setup.c
@@ -55,7 +55,7 @@ int mpidr_to_cpu(uint64_t mpidr)
return -1;
}
-static void cpu_set(int fdtnode __unused, u64 regval, void *info __unused)
+static void cpu_set_fdt(int fdtnode __unused, u64 regval, void *info __unused)
{
int cpu = nr_cpus++;
@@ -65,13 +65,49 @@ static void cpu_set(int fdtnode __unused, u64 regval, void *info __unused)
set_cpu_present(cpu, true);
}
+#ifdef CONFIG_EFI
+
+#include <acpi.h>
+
+static int cpu_set_acpi(struct acpi_subtable_header *header)
+{
+ int cpu = nr_cpus++;
+ struct acpi_madt_generic_interrupt *gicc = (void *)header;
+
+ assert_msg(cpu < NR_CPUS, "Number cpus exceeds maximum supported (%d).", NR_CPUS);
+
+ cpus[cpu] = gicc->arm_mpidr;
+ set_cpu_present(cpu, true);
+
+ return 0;
+}
+
+static void cpu_init_acpi(void)
+{
+ acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT, cpu_set_acpi);
+}
+
+#else
+
+static void cpu_init_acpi(void)
+{
+ assert_msg(false, "ACPI not available");
+}
+
+#endif
+
static void cpu_init(void)
{
int ret;
nr_cpus = 0;
- ret = dt_for_each_cpu_node(cpu_set, NULL);
- assert(ret == 0);
+ if (dt_available()) {
+ ret = dt_for_each_cpu_node(cpu_set_fdt, NULL);
+ assert(ret == 0);
+ } else {
+ cpu_init_acpi();
+ }
+
set_cpu_online(0, true);
}
--
2.25.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* Re: [kvm-unit-tests PATCH v5 14/29] arm64: Add support for cpu initialization through ACPI
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 14/29] arm64: Add support for cpu " Nikos Nikoleris
@ 2023-05-01 12:56 ` Shaoqin Huang
0 siblings, 0 replies; 52+ messages in thread
From: Shaoqin Huang @ 2023-05-01 12:56 UTC (permalink / raw)
To: Nikos Nikoleris, kvm, kvmarm, andrew.jones
Cc: pbonzini, alexandru.elisei, ricarkol, Andrew Jones
On 4/28/23 20:03, Nikos Nikoleris wrote:
> In systems with ACPI support and when a DT is not provided, we can use
> the MADTs to discover the number of CPUs and their corresponding MIDR.
> This change implements this but retains the default behavior; we check
> if a valid DT is provided, if not, we try to discover the cores in the
> system using ACPI.
>
> Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
> Reviewed-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Shaoqin Huang <shahuang@redhat.com>
> ---
> lib/acpi.h | 63 +++++++++++++++++++++++++++++++++++++++++++++++++
> lib/acpi.c | 20 ++++++++++++++++
> lib/arm/setup.c | 42 ++++++++++++++++++++++++++++++---
> 3 files changed, 122 insertions(+), 3 deletions(-)
>
> diff --git a/lib/acpi.h b/lib/acpi.h
> index 04e4d1c3..4a59f543 100644
> --- a/lib/acpi.h
> +++ b/lib/acpi.h
> @@ -17,6 +17,7 @@
> #define XSDT_SIGNATURE ACPI_SIGNATURE('X','S','D','T')
> #define FACP_SIGNATURE ACPI_SIGNATURE('F','A','C','P')
> #define FACS_SIGNATURE ACPI_SIGNATURE('F','A','C','S')
> +#define MADT_SIGNATURE ACPI_SIGNATURE('A','P','I','C')
> #define SPCR_SIGNATURE ACPI_SIGNATURE('S','P','C','R')
> #define GTDT_SIGNATURE ACPI_SIGNATURE('G','T','D','T')
>
> @@ -147,6 +148,67 @@ struct acpi_table_facs_rev1 {
> u8 reserved3[40]; /* Reserved - must be zero */
> };
>
> +struct acpi_table_madt {
> + ACPI_TABLE_HEADER_DEF /* ACPI common table header */
> + u32 address; /* Physical address of local APIC */
> + u32 flags;
> +};
> +
> +struct acpi_subtable_header {
> + u8 type;
> + u8 length;
> +};
> +
> +typedef int (*acpi_table_handler)(struct acpi_subtable_header *header);
> +
> +/* 11: Generic interrupt - GICC (ACPI 5.0 + ACPI 6.0 + ACPI 6.3 changes) */
> +
> +struct acpi_madt_generic_interrupt {
> + u8 type;
> + u8 length;
> + u16 reserved; /* reserved - must be zero */
> + u32 cpu_interface_number;
> + u32 uid;
> + u32 flags;
> + u32 parking_version;
> + u32 performance_interrupt;
> + u64 parked_address;
> + u64 base_address;
> + u64 gicv_base_address;
> + u64 gich_base_address;
> + u32 vgic_interrupt;
> + u64 gicr_base_address;
> + u64 arm_mpidr;
> + u8 efficiency_class;
> + u8 reserved2[1];
> + u16 spe_interrupt; /* ACPI 6.3 */
> +};
> +
> +/* Values for MADT subtable type in struct acpi_subtable_header */
> +
> +enum acpi_madt_type {
> + ACPI_MADT_TYPE_LOCAL_APIC = 0,
> + ACPI_MADT_TYPE_IO_APIC = 1,
> + ACPI_MADT_TYPE_INTERRUPT_OVERRIDE = 2,
> + ACPI_MADT_TYPE_NMI_SOURCE = 3,
> + ACPI_MADT_TYPE_LOCAL_APIC_NMI = 4,
> + ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE = 5,
> + ACPI_MADT_TYPE_IO_SAPIC = 6,
> + ACPI_MADT_TYPE_LOCAL_SAPIC = 7,
> + ACPI_MADT_TYPE_INTERRUPT_SOURCE = 8,
> + ACPI_MADT_TYPE_LOCAL_X2APIC = 9,
> + ACPI_MADT_TYPE_LOCAL_X2APIC_NMI = 10,
> + ACPI_MADT_TYPE_GENERIC_INTERRUPT = 11,
> + ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR = 12,
> + ACPI_MADT_TYPE_GENERIC_MSI_FRAME = 13,
> + ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR = 14,
> + ACPI_MADT_TYPE_GENERIC_TRANSLATOR = 15,
> + ACPI_MADT_TYPE_RESERVED = 16 /* 16 and greater are reserved */
> +};
> +
> +/* MADT Local APIC flags */
> +#define ACPI_MADT_ENABLED (1) /* 00: Processor is usable if set */
> +
> struct spcr_descriptor {
> ACPI_TABLE_HEADER_DEF /* ACPI common table header */
> u8 interface_type; /* 0=full 16550, 1=subset of 16550 */
> @@ -192,5 +254,6 @@ struct acpi_table_gtdt {
>
> void set_efi_rsdp(struct acpi_table_rsdp *rsdp);
> void *find_acpi_table_addr(u32 sig);
> +void acpi_table_parse_madt(enum acpi_madt_type mtype, acpi_table_handler handler);
>
> #endif
> diff --git a/lib/acpi.c b/lib/acpi.c
> index a197f3dd..bbe33d08 100644
> --- a/lib/acpi.c
> +++ b/lib/acpi.c
> @@ -102,3 +102,23 @@ void *find_acpi_table_addr(u32 sig)
>
> return NULL;
> }
> +
> +void acpi_table_parse_madt(enum acpi_madt_type mtype, acpi_table_handler handler)
> +{
> + struct acpi_table_madt *madt;
> + struct acpi_subtable_header *header;
> + void *end;
> +
> + madt = find_acpi_table_addr(MADT_SIGNATURE);
> + assert(madt);
> +
> + header = (void *)(ulong) madt + sizeof(struct acpi_table_madt);
> + end = (void *)((ulong) madt + madt->length);
> +
> + while ((void *)header < end) {
> + if (header->type == mtype)
> + handler(header);
> +
> + header = (void *)(ulong) header + header->length;
> + }
> +}
> diff --git a/lib/arm/setup.c b/lib/arm/setup.c
> index 1572c64e..59b0aedd 100644
> --- a/lib/arm/setup.c
> +++ b/lib/arm/setup.c
> @@ -55,7 +55,7 @@ int mpidr_to_cpu(uint64_t mpidr)
> return -1;
> }
>
> -static void cpu_set(int fdtnode __unused, u64 regval, void *info __unused)
> +static void cpu_set_fdt(int fdtnode __unused, u64 regval, void *info __unused)
> {
> int cpu = nr_cpus++;
>
> @@ -65,13 +65,49 @@ static void cpu_set(int fdtnode __unused, u64 regval, void *info __unused)
> set_cpu_present(cpu, true);
> }
>
> +#ifdef CONFIG_EFI
> +
> +#include <acpi.h>
> +
> +static int cpu_set_acpi(struct acpi_subtable_header *header)
> +{
> + int cpu = nr_cpus++;
> + struct acpi_madt_generic_interrupt *gicc = (void *)header;
> +
> + assert_msg(cpu < NR_CPUS, "Number cpus exceeds maximum supported (%d).", NR_CPUS);
> +
> + cpus[cpu] = gicc->arm_mpidr;
> + set_cpu_present(cpu, true);
> +
> + return 0;
> +}
> +
> +static void cpu_init_acpi(void)
> +{
> + acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT, cpu_set_acpi);
> +}
> +
> +#else
> +
> +static void cpu_init_acpi(void)
> +{
> + assert_msg(false, "ACPI not available");
> +}
> +
> +#endif
> +
> static void cpu_init(void)
> {
> int ret;
>
> nr_cpus = 0;
> - ret = dt_for_each_cpu_node(cpu_set, NULL);
> - assert(ret == 0);
> + if (dt_available()) {
> + ret = dt_for_each_cpu_node(cpu_set_fdt, NULL);
> + assert(ret == 0);
> + } else {
> + cpu_init_acpi();
> + }
> +
> set_cpu_online(0, true);
> }
>
--
Shaoqin
^ permalink raw reply [flat|nested] 52+ messages in thread
* [kvm-unit-tests PATCH v5 15/29] arm64: Add support for gic initialization through ACPI
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
` (13 preceding siblings ...)
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 14/29] arm64: Add support for cpu " Nikos Nikoleris
@ 2023-04-28 12:03 ` Nikos Nikoleris
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 16/29] lib/printf: Support for precision modifier in printf Nikos Nikoleris
` (15 subsequent siblings)
30 siblings, 0 replies; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-28 12:03 UTC (permalink / raw)
To: kvm, kvmarm, andrew.jones; +Cc: pbonzini, alexandru.elisei, ricarkol
In systems with ACPI support and when a DT is not provided, we can use
the MADTs to figure out if it implements a GICv2 or a GICv3 and
discover the GIC parameters. This change implements this but retains
the default behavior; we check if a valid DT is provided, if not, we
try to discover the cores in the system using ACPI.
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
---
lib/acpi.h | 44 +++++++++++++++-
lib/libcflat.h | 1 +
lib/acpi.c | 9 +++-
lib/arm/gic.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 189 insertions(+), 4 deletions(-)
diff --git a/lib/acpi.h b/lib/acpi.h
index 4a59f543..202d832e 100644
--- a/lib/acpi.h
+++ b/lib/acpi.h
@@ -184,6 +184,48 @@ struct acpi_madt_generic_interrupt {
u16 spe_interrupt; /* ACPI 6.3 */
};
+/* 12: Generic Distributor (ACPI 5.0 + ACPI 6.0 changes) */
+
+struct acpi_madt_generic_distributor {
+ struct acpi_subtable_header header;
+ u16 reserved; /* reserved - must be zero */
+ u32 gic_id;
+ u64 base_address;
+ u32 global_irq_base;
+ u8 version;
+ u8 reserved2[3]; /* reserved - must be zero */
+};
+
+/* Values for Version field above */
+
+enum acpi_madt_gic_version {
+ ACPI_MADT_GIC_VERSION_NONE = 0,
+ ACPI_MADT_GIC_VERSION_V1 = 1,
+ ACPI_MADT_GIC_VERSION_V2 = 2,
+ ACPI_MADT_GIC_VERSION_V3 = 3,
+ ACPI_MADT_GIC_VERSION_V4 = 4,
+ ACPI_MADT_GIC_VERSION_RESERVED = 5 /* 5 and greater are reserved */
+};
+
+/* 14: Generic Redistributor (ACPI 5.1) */
+
+struct acpi_madt_generic_redistributor {
+ struct acpi_subtable_header header;
+ u16 reserved; /* reserved - must be zero */
+ u64 base_address;
+ u32 length;
+};
+
+/* 15: Generic Translator (ACPI 6.0) */
+
+struct acpi_madt_generic_translator {
+ struct acpi_subtable_header header;
+ u16 reserved; /* reserved - must be zero */
+ u32 translation_id;
+ u64 base_address;
+ u32 reserved2;
+};
+
/* Values for MADT subtable type in struct acpi_subtable_header */
enum acpi_madt_type {
@@ -254,6 +296,6 @@ struct acpi_table_gtdt {
void set_efi_rsdp(struct acpi_table_rsdp *rsdp);
void *find_acpi_table_addr(u32 sig);
-void acpi_table_parse_madt(enum acpi_madt_type mtype, acpi_table_handler handler);
+int acpi_table_parse_madt(enum acpi_madt_type mtype, acpi_table_handler handler);
#endif
diff --git a/lib/libcflat.h b/lib/libcflat.h
index c1fd31ff..700f4352 100644
--- a/lib/libcflat.h
+++ b/lib/libcflat.h
@@ -161,6 +161,7 @@ extern void setup_vm(void);
#define SZ_8K (1 << 13)
#define SZ_16K (1 << 14)
#define SZ_64K (1 << 16)
+#define SZ_128K (1 << 17)
#define SZ_1M (1 << 20)
#define SZ_2M (1 << 21)
#define SZ_1G (1 << 30)
diff --git a/lib/acpi.c b/lib/acpi.c
index bbe33d08..760cd8b2 100644
--- a/lib/acpi.c
+++ b/lib/acpi.c
@@ -103,11 +103,12 @@ void *find_acpi_table_addr(u32 sig)
return NULL;
}
-void acpi_table_parse_madt(enum acpi_madt_type mtype, acpi_table_handler handler)
+int acpi_table_parse_madt(enum acpi_madt_type mtype, acpi_table_handler handler)
{
struct acpi_table_madt *madt;
struct acpi_subtable_header *header;
void *end;
+ int count = 0;
madt = find_acpi_table_addr(MADT_SIGNATURE);
assert(madt);
@@ -116,9 +117,13 @@ void acpi_table_parse_madt(enum acpi_madt_type mtype, acpi_table_handler handler
end = (void *)((ulong) madt + madt->length);
while ((void *)header < end) {
- if (header->type == mtype)
+ if (header->type == mtype) {
handler(header);
+ count++;
+ }
header = (void *)(ulong) header + header->length;
}
+
+ return count;
}
diff --git a/lib/arm/gic.c b/lib/arm/gic.c
index 89a15fe8..af43a96d 100644
--- a/lib/arm/gic.c
+++ b/lib/arm/gic.c
@@ -3,6 +3,7 @@
*
* This work is licensed under the terms of the GNU LGPL, version 2.
*/
+#include <acpi.h>
#include <devicetree.h>
#include <asm/gic.h>
#include <asm/io.h>
@@ -120,7 +121,7 @@ int gic_version(void)
return 0;
}
-int gic_init(void)
+static int gic_init_fdt(void)
{
if (gicv2_init()) {
gic_common_ops = &gicv2_common_ops;
@@ -133,6 +134,142 @@ int gic_init(void)
return gic_version();
}
+#ifdef CONFIG_EFI
+
+#define ACPI_GICV2_DIST_MEM_SIZE (SZ_4K)
+#define ACPI_GIC_CPU_IF_MEM_SIZE (SZ_8K)
+#define ACPI_GICV3_DIST_MEM_SIZE (SZ_64K)
+#define ACPI_GICV3_ITS_MEM_SIZE (SZ_128K)
+
+static int gic_acpi_version(struct acpi_subtable_header *header)
+{
+ struct acpi_madt_generic_distributor *dist = (void *)header;
+ int version = dist->version;
+
+ if (version == 2)
+ gic_common_ops = &gicv2_common_ops;
+ else if (version == 3)
+ gic_common_ops = &gicv3_common_ops;
+
+ return version;
+}
+
+static int gicv2_acpi_parse_madt_cpu(struct acpi_subtable_header *header)
+{
+ struct acpi_madt_generic_interrupt *gicc = (void *)header;
+ static phys_addr_t gicc_base_address;
+
+ if (!(gicc->flags & ACPI_MADT_ENABLED))
+ return 0;
+
+ if (!gicc_base_address) {
+ gicc_base_address = gicc->base_address;
+ gicv2_data.cpu_base = ioremap(gicc_base_address, ACPI_GIC_CPU_IF_MEM_SIZE);
+ }
+ assert(gicc_base_address == gicc->base_address);
+
+ return 0;
+}
+
+static int gicv2_acpi_parse_madt_dist(struct acpi_subtable_header *header)
+{
+ struct acpi_madt_generic_distributor *dist = (void *)header;
+
+ gicv2_data.dist_base = ioremap(dist->base_address, ACPI_GICV2_DIST_MEM_SIZE);
+
+ return 0;
+}
+
+static int gicv3_acpi_parse_madt_gicc(struct acpi_subtable_header *header)
+{
+ struct acpi_madt_generic_interrupt *gicc = (void *)header;
+ static phys_addr_t gicr_base_address;
+
+ if (!(gicc->flags & ACPI_MADT_ENABLED))
+ return 0;
+
+ if (!gicr_base_address) {
+ gicr_base_address = gicc->gicr_base_address;
+ gicv3_data.redist_bases[0] = ioremap(gicr_base_address, SZ_64K * 2);
+ }
+ assert(gicr_base_address == gicc->gicr_base_address);
+
+ return 0;
+}
+
+static int gicv3_acpi_parse_madt_dist(struct acpi_subtable_header *header)
+{
+ struct acpi_madt_generic_distributor *dist = (void *)header;
+
+ gicv3_data.dist_base = ioremap(dist->base_address, ACPI_GICV3_DIST_MEM_SIZE);
+
+ return 0;
+}
+
+static int gicv3_acpi_parse_madt_redist(struct acpi_subtable_header *header)
+{
+ static int i;
+ struct acpi_madt_generic_redistributor *redist = (void *)header;
+
+ gicv3_data.redist_bases[i++] = ioremap(redist->base_address, redist->length);
+
+ return 0;
+}
+
+static int gicv3_acpi_parse_madt_its(struct acpi_subtable_header *header)
+{
+ struct acpi_madt_generic_translator *its_entry = (void *)header;
+
+ its_data.base = ioremap(its_entry->base_address, ACPI_GICV3_ITS_MEM_SIZE - 1);
+
+ return 0;
+}
+
+static int gic_init_acpi(void)
+{
+ int count;
+
+ acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, gic_acpi_version);
+ if (gic_version() == 2) {
+ acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
+ gicv2_acpi_parse_madt_cpu);
+ acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
+ gicv2_acpi_parse_madt_dist);
+ } else if (gic_version() == 3) {
+ acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
+ gicv3_acpi_parse_madt_dist);
+ count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR,
+ gicv3_acpi_parse_madt_redist);
+ if (!count)
+ acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
+ gicv3_acpi_parse_madt_gicc);
+ acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,
+ gicv3_acpi_parse_madt_its);
+#ifdef __aarch64__
+ its_init();
+#endif
+ }
+
+ return gic_version();
+}
+
+#else
+
+static int gic_init_acpi(void)
+{
+ assert_msg(false, "ACPI not available");
+}
+
+#endif /* CONFIG_EFI */
+
+int gic_init(void)
+{
+ if (dt_available())
+ return gic_init_fdt();
+ else
+ return gic_init_acpi();
+}
+
void gic_enable_defaults(void)
{
if (!gic_common_ops) {
--
2.25.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [kvm-unit-tests PATCH v5 16/29] lib/printf: Support for precision modifier in printf
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
` (14 preceding siblings ...)
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 15/29] arm64: Add support for gic " Nikos Nikoleris
@ 2023-04-28 12:03 ` Nikos Nikoleris
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 17/29] lib/printf: Add support for printing wide strings Nikos Nikoleris
` (14 subsequent siblings)
30 siblings, 0 replies; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-28 12:03 UTC (permalink / raw)
To: kvm, kvmarm, andrew.jones
Cc: pbonzini, alexandru.elisei, ricarkol, Andrew Jones
This follows the typical format of:
printf("%.Ns", *str);
Where N might be a decimal digit string or '*'. This feature is used
by a future change.
See also: man 3 printf
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Andrew Jones <drjones@redhat.com>
---
lib/printf.c | 95 ++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 78 insertions(+), 17 deletions(-)
diff --git a/lib/printf.c b/lib/printf.c
index 383799ec..d600199b 100644
--- a/lib/printf.c
+++ b/lib/printf.c
@@ -6,6 +6,7 @@
*/
#include "libcflat.h"
+#include "ctype.h"
#define BUFSZ 2000
@@ -19,6 +20,7 @@ typedef struct strprops {
char pad;
int npad;
bool alternate;
+ int precision;
} strprops_t;
static void addchar(pstream_t *p, char c)
@@ -43,7 +45,7 @@ static void print_str(pstream_t *p, const char *s, strprops_t props)
}
}
- while (*s)
+ while (*s && props.precision--)
addchar(p, *s++);
if (npad < 0) {
@@ -73,12 +75,13 @@ static void print_int(pstream_t *ps, long long n, int base, strprops_t props)
n /= base;
}
+ while (p == buf || (p - buf < props.precision))
+ *p++ = '0';
+ props.precision = -1;
+
if (s)
*p++ = '-';
- if (p == buf)
- *p++ = '0';
-
for (i = 0; i < (p - buf) / 2; ++i) {
char tmp;
@@ -104,8 +107,13 @@ static void print_unsigned(pstream_t *ps, unsigned long long n, int base,
}
if (p == buf)
+ props.alternate = false;
+
+ while (p == buf || (p - buf < props.precision))
*p++ = '0';
- else if (props.alternate && base == 16) {
+ props.precision = -1;
+
+ if (props.alternate && base == 16) {
if (props.pad == '0') {
addchar(ps, '0');
addchar(ps, 'x');
@@ -147,9 +155,56 @@ static int fmtnum(const char **fmt)
return num;
}
+/*
+ * Adapted from drivers/firmware/efi/libstub/vsprintf.c
+ */
+static int skip_atoi(const char **s)
+{
+ int i = 0;
+
+ do {
+ i = i*10 + *((*s)++) - '0';
+ } while (isdigit(**s));
+
+ return i;
+}
+
+/*
+ * Adapted from drivers/firmware/efi/libstub/vsprintf.c
+ */
+static int get_int(const char **fmt, va_list *ap)
+{
+ if (isdigit(**fmt))
+ return skip_atoi(fmt);
+
+ if (**fmt == '*') {
+ ++(*fmt);
+ /* it's the next argument */
+ return va_arg(*ap, int);
+ }
+ return 0;
+}
+
int vsnprintf(char *buf, int size, const char *fmt, va_list va)
{
pstream_t s;
+ va_list args;
+
+ /*
+ * We want to pass our input va_list to helper functions by reference,
+ * but there's an annoying edge case. If va_list was originally passed
+ * to us by value, we could just pass &ap down to the helpers. This is
+ * the case on, for example, X86_32.
+ * However, on X86_64 (and possibly others), va_list is actually a
+ * size-1 array containing a structure. Our function parameter ap has
+ * decayed from T[1] to T*, and &ap has type T** rather than T(*)[1],
+ * which is what will be expected by a function taking a va_list *
+ * parameter.
+ * One standard way to solve this mess is by creating a copy in a local
+ * variable of type va_list and then passing a pointer to that local
+ * copy instead, which is what we do here.
+ */
+ va_copy(args, va);
s.buffer = buf;
s.remain = size - 1;
@@ -160,6 +215,7 @@ int vsnprintf(char *buf, int size, const char *fmt, va_list va)
strprops_t props;
memset(&props, 0, sizeof(props));
props.pad = ' ';
+ props.precision = -1;
if (f != '%') {
addchar(&s, f);
@@ -172,11 +228,15 @@ morefmt:
addchar(&s, '%');
break;
case 'c':
- addchar(&s, va_arg(va, int));
+ addchar(&s, va_arg(args, int));
break;
case '\0':
--fmt;
break;
+ case '.':
+ props.pad = ' ';
+ props.precision = get_int(&fmt, &args);
+ goto morefmt;
case '#':
props.alternate = true;
goto morefmt;
@@ -204,54 +264,55 @@ morefmt:
case 'd':
switch (nlong) {
case 0:
- print_int(&s, va_arg(va, int), 10, props);
+ print_int(&s, va_arg(args, int), 10, props);
break;
case 1:
- print_int(&s, va_arg(va, long), 10, props);
+ print_int(&s, va_arg(args, long), 10, props);
break;
default:
- print_int(&s, va_arg(va, long long), 10, props);
+ print_int(&s, va_arg(args, long long), 10, props);
break;
}
break;
case 'u':
switch (nlong) {
case 0:
- print_unsigned(&s, va_arg(va, unsigned), 10, props);
+ print_unsigned(&s, va_arg(args, unsigned int), 10, props);
break;
case 1:
- print_unsigned(&s, va_arg(va, unsigned long), 10, props);
+ print_unsigned(&s, va_arg(args, unsigned long), 10, props);
break;
default:
- print_unsigned(&s, va_arg(va, unsigned long long), 10, props);
+ print_unsigned(&s, va_arg(args, unsigned long long), 10, props);
break;
}
break;
case 'x':
switch (nlong) {
case 0:
- print_unsigned(&s, va_arg(va, unsigned), 16, props);
+ print_unsigned(&s, va_arg(args, unsigned int), 16, props);
break;
case 1:
- print_unsigned(&s, va_arg(va, unsigned long), 16, props);
+ print_unsigned(&s, va_arg(args, unsigned long), 16, props);
break;
default:
- print_unsigned(&s, va_arg(va, unsigned long long), 16, props);
+ print_unsigned(&s, va_arg(args, unsigned long long), 16, props);
break;
}
break;
case 'p':
props.alternate = true;
- print_unsigned(&s, (unsigned long)va_arg(va, void *), 16, props);
+ print_unsigned(&s, (unsigned long)va_arg(args, void *), 16, props);
break;
case 's':
- print_str(&s, va_arg(va, const char *), props);
+ print_str(&s, va_arg(args, const char *), props);
break;
default:
addchar(&s, f);
break;
}
}
+ va_end(args);
*s.buffer = 0;
return s.added;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [kvm-unit-tests PATCH v5 17/29] lib/printf: Add support for printing wide strings
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
` (15 preceding siblings ...)
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 16/29] lib/printf: Support for precision modifier in printf Nikos Nikoleris
@ 2023-04-28 12:03 ` Nikos Nikoleris
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 18/29] lib/efi: Add support for getting the cmdline Nikos Nikoleris
` (13 subsequent siblings)
30 siblings, 0 replies; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-28 12:03 UTC (permalink / raw)
To: kvm, kvmarm, andrew.jones; +Cc: pbonzini, alexandru.elisei, ricarkol
This change adds support for wide strings (u16*) to printf()
variants. This feature is used by a future change.
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Ricardo Koller <ricarkol@google.com>
---
lib/printf.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 100 insertions(+), 1 deletion(-)
diff --git a/lib/printf.c b/lib/printf.c
index d600199b..27041bb4 100644
--- a/lib/printf.c
+++ b/lib/printf.c
@@ -58,6 +58,102 @@ static void print_str(pstream_t *p, const char *s, strprops_t props)
}
}
+/*
+ * Adapted from drivers/firmware/efi/libstub/vsprintf.c
+ */
+static u32 utf16_to_utf32(const u16 **s16)
+{
+ u16 c0, c1;
+
+ c0 = *(*s16)++;
+ /* not a surrogate */
+ if ((c0 & 0xf800) != 0xd800)
+ return c0;
+ /* invalid: low surrogate instead of high */
+ if (c0 & 0x0400)
+ return 0xfffd;
+ c1 = **s16;
+ /* invalid: missing low surrogate */
+ if ((c1 & 0xfc00) != 0xdc00)
+ return 0xfffd;
+ /* valid surrogate pair */
+ ++(*s16);
+ return (0x10000 - (0xd800 << 10) - 0xdc00) + (c0 << 10) + c1;
+}
+
+/*
+ * Adapted from drivers/firmware/efi/libstub/vsprintf.c
+ */
+static size_t utf16s_utf8nlen(const u16 *s16, size_t maxlen)
+{
+ size_t len, clen;
+
+ for (len = 0; len < maxlen && *s16; len += clen) {
+ u16 c0 = *s16++;
+
+ /* First, get the length for a BMP character */
+ clen = 1 + (c0 >= 0x80) + (c0 >= 0x800);
+ if (len + clen > maxlen)
+ break;
+ /*
+ * If this is a high surrogate, and we're already at maxlen, we
+ * can't include the character if it's a valid surrogate pair.
+ * Avoid accessing one extra word just to check if it's valid
+ * or not.
+ */
+ if ((c0 & 0xfc00) == 0xd800) {
+ if (len + clen == maxlen)
+ break;
+ if ((*s16 & 0xfc00) == 0xdc00) {
+ ++s16;
+ ++clen;
+ }
+ }
+ }
+
+ return len;
+}
+
+/*
+ * Adapted from drivers/firmware/efi/libstub/vsprintf.c
+ */
+static void print_wstring(pstream_t *p, const u16 *s, strprops_t props)
+{
+ const u16 *ws = (const u16 *)s;
+ size_t pos = 0, size = p->remain + 1, len = utf16s_utf8nlen(ws, props.precision);
+
+ while (len-- > 0) {
+ u32 c32 = utf16_to_utf32(&ws);
+ u8 *s8;
+ size_t clen;
+
+ if (c32 < 0x80) {
+ addchar(p, c32);
+ continue;
+ }
+
+ /* Number of trailing octets */
+ clen = 1 + (c32 >= 0x800) + (c32 >= 0x10000);
+
+ len -= clen;
+ s8 = (u8 *)(p->buffer - p->added + pos);
+
+ /* Avoid writing partial character */
+ addchar(p, '\0');
+ pos += clen;
+ if (pos >= size)
+ continue;
+
+ /* Set high bits of leading octet */
+ *s8 = (0xf00 >> 1) >> clen;
+ /* Write trailing octets in reverse order */
+ for (s8 += clen; clen; --clen, c32 >>= 6)
+ *s8-- = 0x80 | (c32 & 0x3f);
+ /* Set low bits of leading octet */
+ *s8 |= c32;
+ }
+}
+
static char digits[16] = "0123456789abcdef";
static void print_int(pstream_t *ps, long long n, int base, strprops_t props)
@@ -305,7 +401,10 @@ morefmt:
print_unsigned(&s, (unsigned long)va_arg(args, void *), 16, props);
break;
case 's':
- print_str(&s, va_arg(args, const char *), props);
+ if (nlong)
+ print_wstring(&s, va_arg(args, const u16 *), props);
+ else
+ print_str(&s, va_arg(args, const char *), props);
break;
default:
addchar(&s, f);
--
2.25.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [kvm-unit-tests PATCH v5 18/29] lib/efi: Add support for getting the cmdline
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
` (16 preceding siblings ...)
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 17/29] lib/printf: Add support for printing wide strings Nikos Nikoleris
@ 2023-04-28 12:03 ` Nikos Nikoleris
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 19/29] arm/arm64: Rename etext to _etext Nikos Nikoleris
` (12 subsequent siblings)
30 siblings, 0 replies; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-28 12:03 UTC (permalink / raw)
To: kvm, kvmarm, andrew.jones; +Cc: pbonzini, alexandru.elisei, ricarkol
This change adds support for discovering the command line arguments,
as a string. Then, we parse this string to populate __argc and __argv
for EFI tests.
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
---
lib/linux/efi.h | 20 ++++++++++
lib/argv.h | 1 +
lib/argv.c | 2 +-
lib/efi.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 124 insertions(+), 1 deletion(-)
diff --git a/lib/linux/efi.h b/lib/linux/efi.h
index 455625aa..9a1cf87b 100644
--- a/lib/linux/efi.h
+++ b/lib/linux/efi.h
@@ -60,6 +60,8 @@ typedef guid_t efi_guid_t;
#define ACPI_TABLE_GUID EFI_GUID(0xeb9d2d30, 0x2d88, 0x11d3, 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
+#define LOADED_IMAGE_PROTOCOL_GUID EFI_GUID(0x5b1b31a1, 0x9562, 0x11d2, 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
+
typedef struct {
efi_guid_t guid;
void *table;
@@ -416,6 +418,24 @@ struct efi_boot_memmap {
unsigned long *buff_size;
};
+#define __aligned_u64 u64 __attribute__((aligned(8)))
+
+struct efi_loaded_image_64 {
+ u32 revision;
+ efi_handle_t parent_handle;
+ efi_system_table_t *system_table;
+ efi_handle_t device_handle;
+ void *file_path;
+ void *reserved;
+ u32 load_options_size;
+ void *load_options;
+ void *image_base;
+ __aligned_u64 image_size;
+ unsigned int image_code_type;
+ unsigned int image_data_type;
+ efi_status_t (__efiapi * unload)(efi_handle_t image_handle);
+};
+
#define efi_bs_call(func, ...) efi_system_table->boottime->func(__VA_ARGS__)
#define efi_rs_call(func, ...) efi_system_table->runtime->func(__VA_ARGS__)
diff --git a/lib/argv.h b/lib/argv.h
index 1fd746dc..0fa77725 100644
--- a/lib/argv.h
+++ b/lib/argv.h
@@ -9,6 +9,7 @@
#define _ARGV_H_
extern void __setup_args(void);
+extern void setup_args(const char *args);
extern void setup_args_progname(const char *args);
extern void setup_env(char *env, int size);
extern void add_setup_arg(const char *arg);
diff --git a/lib/argv.c b/lib/argv.c
index 9ffa673e..fa5ff9ae 100644
--- a/lib/argv.c
+++ b/lib/argv.c
@@ -41,7 +41,7 @@ void __setup_args(void)
__argc = argv - __argv;
}
-static void setup_args(const char *args)
+void setup_args(const char *args)
{
if (!args)
return;
diff --git a/lib/efi.c b/lib/efi.c
index 64cc9789..f524ec9b 100644
--- a/lib/efi.c
+++ b/lib/efi.c
@@ -8,6 +8,9 @@
*/
#include "efi.h"
+#include <argv.h>
+#include <stdlib.h>
+#include <ctype.h>
#include <libcflat.h>
#include <asm/setup.h>
@@ -96,6 +99,80 @@ static void efi_exit(efi_status_t code)
efi_rs_call(reset_system, EFI_RESET_SHUTDOWN, code, 0, NULL);
}
+/* Adapted from drivers/firmware/efi/libstub/efi-stub.c */
+static char *efi_convert_cmdline(struct efi_loaded_image_64 *image, int *cmd_line_len)
+{
+ const u16 *s2;
+ unsigned long cmdline_addr = 0;
+ int options_chars = image->load_options_size;
+ const u16 *options = image->load_options;
+ int options_bytes = 0, safe_options_bytes = 0; /* UTF-8 bytes */
+ bool in_quote = false;
+ efi_status_t status;
+ const int COMMAND_LINE_SIZE = 2048;
+
+ if (options) {
+ s2 = options;
+ while (options_bytes < COMMAND_LINE_SIZE && options_chars--) {
+ u16 c = *s2++;
+
+ if (c < 0x80) {
+ if (c == L'\0' || c == L'\n')
+ break;
+ if (c == L'"')
+ in_quote = !in_quote;
+ else if (!in_quote && isspace((char)c))
+ safe_options_bytes = options_bytes;
+
+ options_bytes++;
+ continue;
+ }
+
+ /*
+ * Get the number of UTF-8 bytes corresponding to a
+ * UTF-16 character.
+ * The first part handles everything in the BMP.
+ */
+ options_bytes += 2 + (c >= 0x800);
+ /*
+ * Add one more byte for valid surrogate pairs. Invalid
+ * surrogates will be replaced with 0xfffd and take up
+ * only 3 bytes.
+ */
+ if ((c & 0xfc00) == 0xd800) {
+ /*
+ * If the very last word is a high surrogate,
+ * we must ignore it since we can't access the
+ * low surrogate.
+ */
+ if (!options_chars) {
+ options_bytes -= 3;
+ } else if ((*s2 & 0xfc00) == 0xdc00) {
+ options_bytes++;
+ options_chars--;
+ s2++;
+ }
+ }
+ }
+ if (options_bytes >= COMMAND_LINE_SIZE) {
+ options_bytes = safe_options_bytes;
+ printf("Command line is too long: truncated to %d bytes\n",
+ options_bytes);
+ }
+ }
+
+ options_bytes++; /* NUL termination */
+
+ status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, options_bytes, (void **)&cmdline_addr);
+ if (status != EFI_SUCCESS)
+ return NULL;
+
+ snprintf((char *)cmdline_addr, options_bytes, "%.*ls", options_bytes - 1, options);
+
+ *cmd_line_len = options_bytes;
+ return (char *)cmdline_addr;
+}
+
efi_status_t efi_main(efi_handle_t handle, efi_system_table_t *sys_tab)
{
int ret;
@@ -109,6 +186,31 @@ efi_status_t efi_main(efi_handle_t handle, efi_system_table_t *sys_tab)
unsigned long map_size = 0, desc_size = 0, key = 0, buff_size = 0;
u32 desc_ver;
+ /* Helper variables needed to get the cmdline */
+ struct efi_loaded_image_64 *image;
+ efi_guid_t loaded_image_proto = LOADED_IMAGE_PROTOCOL_GUID;
+ char *cmdline_ptr = NULL;
+ int cmdline_size = 0;
+
+ /*
+ * Get a handle to the loaded image protocol. This is used to get
+ * information about the running image, such as size and the command
+ * line.
+ */
+ status = efi_bs_call(handle_protocol, handle, &loaded_image_proto, (void *)&image);
+ if (status != EFI_SUCCESS) {
+ printf("Failed to get loaded image protocol\n");
+ goto efi_main_error;
+ }
+
+ cmdline_ptr = efi_convert_cmdline(image, &cmdline_size);
+ if (!cmdline_ptr) {
+ printf("getting command line via LOADED_IMAGE_PROTOCOL\n");
+ status = EFI_OUT_OF_RESOURCES;
+ goto efi_main_error;
+ }
+ setup_args(cmdline_ptr);
+
/* Set up efi_bootinfo */
efi_bootinfo.mem_map.map = ↦
efi_bootinfo.mem_map.map_size = &map_size;
--
2.25.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [kvm-unit-tests PATCH v5 19/29] arm/arm64: Rename etext to _etext
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
` (17 preceding siblings ...)
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 18/29] lib/efi: Add support for getting the cmdline Nikos Nikoleris
@ 2023-04-28 12:03 ` Nikos Nikoleris
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 20/29] lib: Avoid ms_abi for calls related to EFI on arm64 Nikos Nikoleris
` (11 subsequent siblings)
30 siblings, 0 replies; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-28 12:03 UTC (permalink / raw)
To: kvm, kvmarm, andrew.jones
Cc: Andrew Jones, pbonzini, alexandru.elisei, ricarkol
From: Andrew Jones <drjones@redhat.com>
Rename etext to the more popular _etext allowing different linker
scripts to more easily be used.
Signed-off-by: Andrew Jones <drjones@redhat.com>
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Ricardo Koller <ricarkol@google.com>
---
lib/arm/setup.c | 4 ++--
arm/flat.lds | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/arm/setup.c b/lib/arm/setup.c
index 59b0aedd..03a4098e 100644
--- a/lib/arm/setup.c
+++ b/lib/arm/setup.c
@@ -33,7 +33,7 @@
#define NR_EXTRA_MEM_REGIONS 16
#define NR_INITIAL_MEM_REGIONS (MAX_DT_MEM_REGIONS + NR_EXTRA_MEM_REGIONS)
-extern unsigned long etext;
+extern unsigned long _etext;
char *initrd;
u32 initrd_size;
@@ -157,7 +157,7 @@ unsigned int mem_region_get_flags(phys_addr_t paddr)
static void mem_regions_add_assumed(void)
{
- phys_addr_t code_end = (phys_addr_t)(unsigned long)&etext;
+ phys_addr_t code_end = (phys_addr_t)(unsigned long)&_etext;
struct mem_region *r;
r = mem_region_find(code_end - 1);
diff --git a/arm/flat.lds b/arm/flat.lds
index 47fcb649..9016ac9f 100644
--- a/arm/flat.lds
+++ b/arm/flat.lds
@@ -27,7 +27,7 @@ SECTIONS
PROVIDE(_text = .);
.text : { *(.init) *(.text) *(.text.*) }
. = ALIGN(64K);
- PROVIDE(etext = .);
+ PROVIDE(_etext = .);
PROVIDE(reloc_start = .);
.rela.dyn : { *(.rela.dyn) }
--
2.25.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [kvm-unit-tests PATCH v5 20/29] lib: Avoid ms_abi for calls related to EFI on arm64
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
` (18 preceding siblings ...)
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 19/29] arm/arm64: Rename etext to _etext Nikos Nikoleris
@ 2023-04-28 12:03 ` Nikos Nikoleris
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 21/29] arm64: Add a new type of memory type flag MR_F_RESERVED Nikos Nikoleris
` (10 subsequent siblings)
30 siblings, 0 replies; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-28 12:03 UTC (permalink / raw)
To: kvm, kvmarm, andrew.jones
Cc: pbonzini, alexandru.elisei, ricarkol, Andrew Jones
x86_64 requires that EFI calls use the ms_abi calling convention. For
arm64 this is unnecessary.
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Andrew Jones <drjones@redhat.com>
---
lib/linux/efi.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/lib/linux/efi.h b/lib/linux/efi.h
index 9a1cf87b..53748dd4 100644
--- a/lib/linux/efi.h
+++ b/lib/linux/efi.h
@@ -33,7 +33,11 @@ typedef u16 efi_char16_t; /* UNICODE character */
typedef u64 efi_physical_addr_t;
typedef void *efi_handle_t;
+#ifdef __x86_64__
#define __efiapi __attribute__((ms_abi))
+#else
+#define __efiapi
+#endif
/*
* The UEFI spec and EDK2 reference implementation both define EFI_GUID as
--
2.25.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [kvm-unit-tests PATCH v5 21/29] arm64: Add a new type of memory type flag MR_F_RESERVED
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
` (19 preceding siblings ...)
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 20/29] lib: Avoid ms_abi for calls related to EFI on arm64 Nikos Nikoleris
@ 2023-04-28 12:03 ` Nikos Nikoleris
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 22/29] arm64: Add a setup sequence for systems that boot through EFI Nikos Nikoleris
` (9 subsequent siblings)
30 siblings, 0 replies; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-28 12:03 UTC (permalink / raw)
To: kvm, kvmarm, andrew.jones
Cc: Andrew Jones, pbonzini, alexandru.elisei, ricarkol
From: Andrew Jones <drjones@redhat.com>
This will be used by future change to add PTE entries for special EFI
memory regions.
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Ricardo Koller <ricarkol@google.com>
---
lib/arm/asm/setup.h | 1 +
lib/arm/mmu.c | 4 ++++
2 files changed, 5 insertions(+)
diff --git a/lib/arm/asm/setup.h b/lib/arm/asm/setup.h
index f0e70b11..64cd379b 100644
--- a/lib/arm/asm/setup.h
+++ b/lib/arm/asm/setup.h
@@ -15,6 +15,7 @@ extern int nr_cpus;
#define MR_F_IO (1U << 0)
#define MR_F_CODE (1U << 1)
+#define MR_F_RESERVED (1U << 2)
#define MR_F_UNKNOWN (1U << 31)
struct mem_region {
diff --git a/lib/arm/mmu.c b/lib/arm/mmu.c
index 18e32b2b..2f4ec815 100644
--- a/lib/arm/mmu.c
+++ b/lib/arm/mmu.c
@@ -222,6 +222,10 @@ void *setup_mmu(phys_addr_t phys_end, void *unused)
for (r = mem_regions; r->end; ++r) {
if (r->flags & MR_F_IO) {
continue;
+ } else if (r->flags & MR_F_RESERVED) {
+ /* Reserved pages need to be writable for whatever reserved them */
+ mmu_set_range_ptes(mmu_idmap, r->start, r->start, r->end,
+ __pgprot(PTE_WBWA));
} else if (r->flags & MR_F_CODE) {
/* armv8 requires code shared between EL1 and EL0 to be read-only */
mmu_set_range_ptes(mmu_idmap, r->start, r->start, r->end,
--
2.25.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [kvm-unit-tests PATCH v5 22/29] arm64: Add a setup sequence for systems that boot through EFI
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
` (20 preceding siblings ...)
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 21/29] arm64: Add a new type of memory type flag MR_F_RESERVED Nikos Nikoleris
@ 2023-04-28 12:03 ` Nikos Nikoleris
2023-05-01 12:59 ` Shaoqin Huang
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 23/29] arm64: Copy code from GNU-EFI Nikos Nikoleris
` (8 subsequent siblings)
30 siblings, 1 reply; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-28 12:03 UTC (permalink / raw)
To: kvm, kvmarm, andrew.jones; +Cc: pbonzini, alexandru.elisei, ricarkol
This change implements an alternative setup sequence for the system
when we are booting through EFI. The memory map is discovered through
EFI boot services and devices through ACPI.
This change is based on a change initially proposed by
Andrew Jones <drjones@redhat.com>
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
---
lib/linux/efi.h | 1 +
lib/arm/asm/setup.h | 8 ++
lib/arm/setup.c | 186 +++++++++++++++++++++++++++++++++++++++++++-
arm/cstart.S | 1 +
arm/cstart64.S | 1 +
5 files changed, 194 insertions(+), 3 deletions(-)
diff --git a/lib/linux/efi.h b/lib/linux/efi.h
index 53748dd4..89f9a9e0 100644
--- a/lib/linux/efi.h
+++ b/lib/linux/efi.h
@@ -63,6 +63,7 @@ typedef guid_t efi_guid_t;
(c) & 0xff, ((c) >> 8) & 0xff, d } }
#define ACPI_TABLE_GUID EFI_GUID(0xeb9d2d30, 0x2d88, 0x11d3, 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
+#define ACPI_20_TABLE_GUID EFI_GUID(0x8868e871, 0xe4f1, 0x11d3, 0xbc, 0x22, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81)
#define LOADED_IMAGE_PROTOCOL_GUID EFI_GUID(0x5b1b31a1, 0x9562, 0x11d2, 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
diff --git a/lib/arm/asm/setup.h b/lib/arm/asm/setup.h
index 64cd379b..06069116 100644
--- a/lib/arm/asm/setup.h
+++ b/lib/arm/asm/setup.h
@@ -38,4 +38,12 @@ extern unsigned int mem_region_get_flags(phys_addr_t paddr);
void setup(const void *fdt, phys_addr_t freemem_start);
+#ifdef CONFIG_EFI
+
+#include <efi.h>
+
+efi_status_t setup_efi(efi_bootinfo_t *efi_bootinfo);
+
+#endif
+
#endif /* _ASMARM_SETUP_H_ */
diff --git a/lib/arm/setup.c b/lib/arm/setup.c
index 03a4098e..c4f495a9 100644
--- a/lib/arm/setup.c
+++ b/lib/arm/setup.c
@@ -30,10 +30,10 @@
#include "io.h"
#define MAX_DT_MEM_REGIONS 16
-#define NR_EXTRA_MEM_REGIONS 16
+#define NR_EXTRA_MEM_REGIONS 64
#define NR_INITIAL_MEM_REGIONS (MAX_DT_MEM_REGIONS + NR_EXTRA_MEM_REGIONS)
-extern unsigned long _etext;
+extern unsigned long _text, _etext, _data, _edata;
char *initrd;
u32 initrd_size;
@@ -43,7 +43,10 @@ int nr_cpus;
static struct mem_region __initial_mem_regions[NR_INITIAL_MEM_REGIONS + 1];
struct mem_region *mem_regions = __initial_mem_regions;
-phys_addr_t __phys_offset, __phys_end;
+phys_addr_t __phys_offset = (phys_addr_t)-1, __phys_end = 0;
+
+extern void exceptions_init(void);
+extern void asm_mmu_disable(void);
int mpidr_to_cpu(uint64_t mpidr)
{
@@ -289,3 +292,180 @@ void setup(const void *fdt, phys_addr_t freemem_start)
if (!(auxinfo.flags & AUXINFO_MMU_OFF))
setup_vm();
}
+
+#ifdef CONFIG_EFI
+
+#include <efi.h>
+
+static efi_status_t setup_rsdp(efi_bootinfo_t *efi_bootinfo)
+{
+ efi_status_t status;
+ struct acpi_table_rsdp *rsdp;
+
+ /*
+ * RSDP resides in an EFI_ACPI_RECLAIM_MEMORY region, which is not used
+ * by kvm-unit-tests arm64 memory allocator. So it is not necessary to
+ * copy the data structure to another memory region to prevent
+ * unintentional overwrite.
+ */
+ status = efi_get_system_config_table(ACPI_20_TABLE_GUID, (void **)&rsdp);
+ if (status != EFI_SUCCESS)
+ return status;
+
+ set_efi_rsdp(rsdp);
+
+ return EFI_SUCCESS;
+}
+
+static efi_status_t efi_mem_init(efi_bootinfo_t *efi_bootinfo)
+{
+ int i;
+ unsigned long free_mem_pages = 0;
+ unsigned long free_mem_start = 0;
+ struct efi_boot_memmap *map = &(efi_bootinfo->mem_map);
+ efi_memory_desc_t *buffer = *map->map;
+ efi_memory_desc_t *d = NULL;
+ phys_addr_t base, top;
+ struct mem_region r;
+ uintptr_t text = (uintptr_t)&_text, etext = __ALIGN((uintptr_t)&_etext, 4096);
+ uintptr_t data = (uintptr_t)&_data, edata = __ALIGN((uintptr_t)&_edata, 4096);
+
+ /*
+ * Record the largest free EFI_CONVENTIONAL_MEMORY region
+ * which will be used to set up the memory allocator, so that
+ * the memory allocator can work in the largest free
+ * continuous memory region.
+ */
+ for (i = 0; i < *(map->map_size); i += *(map->desc_size)) {
+ d = (efi_memory_desc_t *)(&((u8 *)buffer)[i]);
+
+ r.start = d->phys_addr;
+ r.end = d->phys_addr + d->num_pages * EFI_PAGE_SIZE;
+ r.flags = 0;
+
+ switch (d->type) {
+ case EFI_RESERVED_TYPE:
+ case EFI_LOADER_DATA:
+ case EFI_BOOT_SERVICES_CODE:
+ case EFI_BOOT_SERVICES_DATA:
+ case EFI_RUNTIME_SERVICES_CODE:
+ case EFI_RUNTIME_SERVICES_DATA:
+ case EFI_UNUSABLE_MEMORY:
+ case EFI_ACPI_RECLAIM_MEMORY:
+ case EFI_ACPI_MEMORY_NVS:
+ case EFI_PAL_CODE:
+ r.flags = MR_F_RESERVED;
+ break;
+ case EFI_MEMORY_MAPPED_IO:
+ case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
+ r.flags = MR_F_IO;
+ break;
+ case EFI_LOADER_CODE:
+ if (r.start <= text && r.end > text) {
+ /* This is the unit test region. Flag the code separately. */
+ phys_addr_t tmp = r.end;
+
+ assert(etext <= data);
+ assert(edata <= r.end);
+ r.flags = MR_F_CODE;
+ r.end = data;
+ mem_region_add(&r);
+ r.start = data;
+ r.end = tmp;
+ r.flags = 0;
+ } else {
+ r.flags = MR_F_RESERVED;
+ }
+ break;
+ case EFI_CONVENTIONAL_MEMORY:
+ if (free_mem_pages < d->num_pages) {
+ free_mem_pages = d->num_pages;
+ free_mem_start = d->phys_addr;
+ }
+ break;
+ }
+
+ if (!(r.flags & MR_F_IO)) {
+ if (r.start < __phys_offset)
+ __phys_offset = r.start;
+ if (r.end > __phys_end)
+ __phys_end = r.end;
+ }
+ mem_region_add(&r);
+ }
+ __phys_end &= PHYS_MASK;
+ asm_mmu_disable();
+
+ if (free_mem_pages == 0)
+ return EFI_OUT_OF_RESOURCES;
+
+ assert(sizeof(long) == 8 || free_mem_start < (3ul << 30));
+
+ phys_alloc_init(free_mem_start, free_mem_pages << EFI_PAGE_SHIFT);
+ phys_alloc_set_minimum_alignment(SMP_CACHE_BYTES);
+
+ phys_alloc_get_unused(&base, &top);
+ base = PAGE_ALIGN(base);
+ top = top & PAGE_MASK;
+ assert(sizeof(long) == 8 || !(base >> 32));
+ if (sizeof(long) != 8 && (top >> 32) != 0)
+ top = ((uint64_t)1 << 32);
+ page_alloc_init_area(0, base >> PAGE_SHIFT, top >> PAGE_SHIFT);
+ page_alloc_ops_enable();
+
+ return EFI_SUCCESS;
+}
+
+efi_status_t setup_efi(efi_bootinfo_t *efi_bootinfo)
+{
+ efi_status_t status;
+
+ struct thread_info *ti = current_thread_info();
+
+ memset(ti, 0, sizeof(*ti));
+
+ exceptions_init();
+
+ status = efi_mem_init(efi_bootinfo);
+ if (status != EFI_SUCCESS) {
+ printf("Failed to initialize memory: ");
+ switch (status) {
+ case EFI_OUT_OF_RESOURCES:
+ printf("No free memory region\n");
+ break;
+ default:
+ printf("Unknown error\n");
+ break;
+ }
+ return status;
+ }
+
+ status = setup_rsdp(efi_bootinfo);
+ if (status != EFI_SUCCESS) {
+ printf("Cannot find RSDP in EFI system table\n");
+ return status;
+ }
+
+ psci_set_conduit();
+ cpu_init();
+ /* cpu_init must be called before thread_info_init */
+ thread_info_init(current_thread_info(), 0);
+ /* mem_init must be called before io_init */
+ io_init();
+
+ timer_save_state();
+ if (initrd) {
+ /* environ is currently the only file in the initrd */
+ char *env = malloc(initrd_size);
+
+ memcpy(env, initrd, initrd_size);
+ setup_env(env, initrd_size);
+ }
+
+ if (!(auxinfo.flags & AUXINFO_MMU_OFF))
+ setup_vm();
+
+ return EFI_SUCCESS;
+}
+
+#endif
diff --git a/arm/cstart.S b/arm/cstart.S
index 7036e67f..3dd71ed9 100644
--- a/arm/cstart.S
+++ b/arm/cstart.S
@@ -242,6 +242,7 @@ asm_mmu_disable:
*
* Input r0 is the stack top, which is the exception stacks base
*/
+.globl exceptions_init
exceptions_init:
mrc p15, 0, r2, c1, c0, 0 @ read SCTLR
bic r2, #CR_V @ SCTLR.V := 0
diff --git a/arm/cstart64.S b/arm/cstart64.S
index e4ab7d06..223c1092 100644
--- a/arm/cstart64.S
+++ b/arm/cstart64.S
@@ -265,6 +265,7 @@ asm_mmu_disable:
* Vectors
*/
+.globl exceptions_init
exceptions_init:
adrp x4, vector_table
add x4, x4, :lo12:vector_table
--
2.25.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* Re: [kvm-unit-tests PATCH v5 22/29] arm64: Add a setup sequence for systems that boot through EFI
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 22/29] arm64: Add a setup sequence for systems that boot through EFI Nikos Nikoleris
@ 2023-05-01 12:59 ` Shaoqin Huang
0 siblings, 0 replies; 52+ messages in thread
From: Shaoqin Huang @ 2023-05-01 12:59 UTC (permalink / raw)
To: Nikos Nikoleris, kvm, kvmarm, andrew.jones
Cc: pbonzini, alexandru.elisei, ricarkol
On 4/28/23 20:03, Nikos Nikoleris wrote:
> This change implements an alternative setup sequence for the system
> when we are booting through EFI. The memory map is discovered through
> EFI boot services and devices through ACPI.
>
> This change is based on a change initially proposed by
> Andrew Jones <drjones@redhat.com>
>
> Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Shaoqin Huang <shahuang@redhat.com>
> ---
> lib/linux/efi.h | 1 +
> lib/arm/asm/setup.h | 8 ++
> lib/arm/setup.c | 186 +++++++++++++++++++++++++++++++++++++++++++-
> arm/cstart.S | 1 +
> arm/cstart64.S | 1 +
> 5 files changed, 194 insertions(+), 3 deletions(-)
>
> diff --git a/lib/linux/efi.h b/lib/linux/efi.h
> index 53748dd4..89f9a9e0 100644
> --- a/lib/linux/efi.h
> +++ b/lib/linux/efi.h
> @@ -63,6 +63,7 @@ typedef guid_t efi_guid_t;
> (c) & 0xff, ((c) >> 8) & 0xff, d } }
>
> #define ACPI_TABLE_GUID EFI_GUID(0xeb9d2d30, 0x2d88, 0x11d3, 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
> +#define ACPI_20_TABLE_GUID EFI_GUID(0x8868e871, 0xe4f1, 0x11d3, 0xbc, 0x22, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81)
>
> #define LOADED_IMAGE_PROTOCOL_GUID EFI_GUID(0x5b1b31a1, 0x9562, 0x11d2, 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
>
> diff --git a/lib/arm/asm/setup.h b/lib/arm/asm/setup.h
> index 64cd379b..06069116 100644
> --- a/lib/arm/asm/setup.h
> +++ b/lib/arm/asm/setup.h
> @@ -38,4 +38,12 @@ extern unsigned int mem_region_get_flags(phys_addr_t paddr);
>
> void setup(const void *fdt, phys_addr_t freemem_start);
>
> +#ifdef CONFIG_EFI
> +
> +#include <efi.h>
> +
> +efi_status_t setup_efi(efi_bootinfo_t *efi_bootinfo);
> +
> +#endif
> +
> #endif /* _ASMARM_SETUP_H_ */
> diff --git a/lib/arm/setup.c b/lib/arm/setup.c
> index 03a4098e..c4f495a9 100644
> --- a/lib/arm/setup.c
> +++ b/lib/arm/setup.c
> @@ -30,10 +30,10 @@
> #include "io.h"
>
> #define MAX_DT_MEM_REGIONS 16
> -#define NR_EXTRA_MEM_REGIONS 16
> +#define NR_EXTRA_MEM_REGIONS 64
> #define NR_INITIAL_MEM_REGIONS (MAX_DT_MEM_REGIONS + NR_EXTRA_MEM_REGIONS)
>
> -extern unsigned long _etext;
> +extern unsigned long _text, _etext, _data, _edata;
>
> char *initrd;
> u32 initrd_size;
> @@ -43,7 +43,10 @@ int nr_cpus;
>
> static struct mem_region __initial_mem_regions[NR_INITIAL_MEM_REGIONS + 1];
> struct mem_region *mem_regions = __initial_mem_regions;
> -phys_addr_t __phys_offset, __phys_end;
> +phys_addr_t __phys_offset = (phys_addr_t)-1, __phys_end = 0;
> +
> +extern void exceptions_init(void);
> +extern void asm_mmu_disable(void);
>
> int mpidr_to_cpu(uint64_t mpidr)
> {
> @@ -289,3 +292,180 @@ void setup(const void *fdt, phys_addr_t freemem_start)
> if (!(auxinfo.flags & AUXINFO_MMU_OFF))
> setup_vm();
> }
> +
> +#ifdef CONFIG_EFI
> +
> +#include <efi.h>
> +
> +static efi_status_t setup_rsdp(efi_bootinfo_t *efi_bootinfo)
> +{
> + efi_status_t status;
> + struct acpi_table_rsdp *rsdp;
> +
> + /*
> + * RSDP resides in an EFI_ACPI_RECLAIM_MEMORY region, which is not used
> + * by kvm-unit-tests arm64 memory allocator. So it is not necessary to
> + * copy the data structure to another memory region to prevent
> + * unintentional overwrite.
> + */
> + status = efi_get_system_config_table(ACPI_20_TABLE_GUID, (void **)&rsdp);
> + if (status != EFI_SUCCESS)
> + return status;
> +
> + set_efi_rsdp(rsdp);
> +
> + return EFI_SUCCESS;
> +}
> +
> +static efi_status_t efi_mem_init(efi_bootinfo_t *efi_bootinfo)
> +{
> + int i;
> + unsigned long free_mem_pages = 0;
> + unsigned long free_mem_start = 0;
> + struct efi_boot_memmap *map = &(efi_bootinfo->mem_map);
> + efi_memory_desc_t *buffer = *map->map;
> + efi_memory_desc_t *d = NULL;
> + phys_addr_t base, top;
> + struct mem_region r;
> + uintptr_t text = (uintptr_t)&_text, etext = __ALIGN((uintptr_t)&_etext, 4096);
> + uintptr_t data = (uintptr_t)&_data, edata = __ALIGN((uintptr_t)&_edata, 4096);
> +
> + /*
> + * Record the largest free EFI_CONVENTIONAL_MEMORY region
> + * which will be used to set up the memory allocator, so that
> + * the memory allocator can work in the largest free
> + * continuous memory region.
> + */
> + for (i = 0; i < *(map->map_size); i += *(map->desc_size)) {
> + d = (efi_memory_desc_t *)(&((u8 *)buffer)[i]);
> +
> + r.start = d->phys_addr;
> + r.end = d->phys_addr + d->num_pages * EFI_PAGE_SIZE;
> + r.flags = 0;
> +
> + switch (d->type) {
> + case EFI_RESERVED_TYPE:
> + case EFI_LOADER_DATA:
> + case EFI_BOOT_SERVICES_CODE:
> + case EFI_BOOT_SERVICES_DATA:
> + case EFI_RUNTIME_SERVICES_CODE:
> + case EFI_RUNTIME_SERVICES_DATA:
> + case EFI_UNUSABLE_MEMORY:
> + case EFI_ACPI_RECLAIM_MEMORY:
> + case EFI_ACPI_MEMORY_NVS:
> + case EFI_PAL_CODE:
> + r.flags = MR_F_RESERVED;
> + break;
> + case EFI_MEMORY_MAPPED_IO:
> + case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
> + r.flags = MR_F_IO;
> + break;
> + case EFI_LOADER_CODE:
> + if (r.start <= text && r.end > text) {
> + /* This is the unit test region. Flag the code separately. */
> + phys_addr_t tmp = r.end;
> +
> + assert(etext <= data);
> + assert(edata <= r.end);
> + r.flags = MR_F_CODE;
> + r.end = data;
> + mem_region_add(&r);
> + r.start = data;
> + r.end = tmp;
> + r.flags = 0;
> + } else {
> + r.flags = MR_F_RESERVED;
> + }
> + break;
> + case EFI_CONVENTIONAL_MEMORY:
> + if (free_mem_pages < d->num_pages) {
> + free_mem_pages = d->num_pages;
> + free_mem_start = d->phys_addr;
> + }
> + break;
> + }
> +
> + if (!(r.flags & MR_F_IO)) {
> + if (r.start < __phys_offset)
> + __phys_offset = r.start;
> + if (r.end > __phys_end)
> + __phys_end = r.end;
> + }
> + mem_region_add(&r);
> + }
> + __phys_end &= PHYS_MASK;
> + asm_mmu_disable();
> +
> + if (free_mem_pages == 0)
> + return EFI_OUT_OF_RESOURCES;
> +
> + assert(sizeof(long) == 8 || free_mem_start < (3ul << 30));
> +
> + phys_alloc_init(free_mem_start, free_mem_pages << EFI_PAGE_SHIFT);
> + phys_alloc_set_minimum_alignment(SMP_CACHE_BYTES);
> +
> + phys_alloc_get_unused(&base, &top);
> + base = PAGE_ALIGN(base);
> + top = top & PAGE_MASK;
> + assert(sizeof(long) == 8 || !(base >> 32));
> + if (sizeof(long) != 8 && (top >> 32) != 0)
> + top = ((uint64_t)1 << 32);
> + page_alloc_init_area(0, base >> PAGE_SHIFT, top >> PAGE_SHIFT);
> + page_alloc_ops_enable();
> +
> + return EFI_SUCCESS;
> +}
> +
> +efi_status_t setup_efi(efi_bootinfo_t *efi_bootinfo)
> +{
> + efi_status_t status;
> +
> + struct thread_info *ti = current_thread_info();
> +
> + memset(ti, 0, sizeof(*ti));
> +
> + exceptions_init();
> +
> + status = efi_mem_init(efi_bootinfo);
> + if (status != EFI_SUCCESS) {
> + printf("Failed to initialize memory: ");
> + switch (status) {
> + case EFI_OUT_OF_RESOURCES:
> + printf("No free memory region\n");
> + break;
> + default:
> + printf("Unknown error\n");
> + break;
> + }
> + return status;
> + }
> +
> + status = setup_rsdp(efi_bootinfo);
> + if (status != EFI_SUCCESS) {
> + printf("Cannot find RSDP in EFI system table\n");
> + return status;
> + }
> +
> + psci_set_conduit();
> + cpu_init();
> + /* cpu_init must be called before thread_info_init */
> + thread_info_init(current_thread_info(), 0);
> + /* mem_init must be called before io_init */
> + io_init();
> +
> + timer_save_state();
> + if (initrd) {
> + /* environ is currently the only file in the initrd */
> + char *env = malloc(initrd_size);
> +
> + memcpy(env, initrd, initrd_size);
> + setup_env(env, initrd_size);
> + }
> +
> + if (!(auxinfo.flags & AUXINFO_MMU_OFF))
> + setup_vm();
> +
> + return EFI_SUCCESS;
> +}
> +
> +#endif
> diff --git a/arm/cstart.S b/arm/cstart.S
> index 7036e67f..3dd71ed9 100644
> --- a/arm/cstart.S
> +++ b/arm/cstart.S
> @@ -242,6 +242,7 @@ asm_mmu_disable:
> *
> * Input r0 is the stack top, which is the exception stacks base
> */
> +.globl exceptions_init
> exceptions_init:
> mrc p15, 0, r2, c1, c0, 0 @ read SCTLR
> bic r2, #CR_V @ SCTLR.V := 0
> diff --git a/arm/cstart64.S b/arm/cstart64.S
> index e4ab7d06..223c1092 100644
> --- a/arm/cstart64.S
> +++ b/arm/cstart64.S
> @@ -265,6 +265,7 @@ asm_mmu_disable:
> * Vectors
> */
>
> +.globl exceptions_init
> exceptions_init:
> adrp x4, vector_table
> add x4, x4, :lo12:vector_table
--
Shaoqin
^ permalink raw reply [flat|nested] 52+ messages in thread
* [kvm-unit-tests PATCH v5 23/29] arm64: Copy code from GNU-EFI
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
` (21 preceding siblings ...)
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 22/29] arm64: Add a setup sequence for systems that boot through EFI Nikos Nikoleris
@ 2023-04-28 12:03 ` Nikos Nikoleris
2023-04-28 12:04 ` [kvm-unit-tests PATCH v5 24/29] arm64: Change GNU-EFI imported code to use defined types Nikos Nikoleris
` (7 subsequent siblings)
30 siblings, 0 replies; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-28 12:03 UTC (permalink / raw)
To: kvm, kvmarm, andrew.jones; +Cc: pbonzini, alexandru.elisei, ricarkol
This change adds unmodified dependencies that we need from GNU-EFI in
order to build arm64 EFI apps.
GNU-EFI sources from https://git.code.sf.net/p/gnu-efi/code v3.0.14
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Ricardo Koller <ricarkol@google.com>
---
arm/efi/elf_aarch64_efi.lds | 63 +++++++++++++++++
arm/efi/crt0-efi-aarch64.S | 130 ++++++++++++++++++++++++++++++++++++
arm/efi/reloc_aarch64.c | 97 +++++++++++++++++++++++++++
3 files changed, 290 insertions(+)
create mode 100644 arm/efi/elf_aarch64_efi.lds
create mode 100644 arm/efi/crt0-efi-aarch64.S
create mode 100644 arm/efi/reloc_aarch64.c
diff --git a/arm/efi/elf_aarch64_efi.lds b/arm/efi/elf_aarch64_efi.lds
new file mode 100644
index 00000000..836d9825
--- /dev/null
+++ b/arm/efi/elf_aarch64_efi.lds
@@ -0,0 +1,63 @@
+OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
+OUTPUT_ARCH(aarch64)
+ENTRY(_start)
+SECTIONS
+{
+ .text 0x0 : {
+ _text = .;
+ *(.text.head)
+ *(.text)
+ *(.text.*)
+ *(.gnu.linkonce.t.*)
+ *(.srodata)
+ *(.rodata*)
+ . = ALIGN(16);
+ }
+ _etext = .;
+ _text_size = . - _text;
+ .dynamic : { *(.dynamic) }
+ .data : ALIGN(4096)
+ {
+ _data = .;
+ *(.sdata)
+ *(.data)
+ *(.data1)
+ *(.data.*)
+ *(.got.plt)
+ *(.got)
+
+ /* the EFI loader doesn't seem to like a .bss section, so we stick
+ it all into .data: */
+ . = ALIGN(16);
+ _bss = .;
+ *(.sbss)
+ *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ . = ALIGN(16);
+ _bss_end = .;
+ }
+
+ .rela.dyn : { *(.rela.dyn) }
+ .rela.plt : { *(.rela.plt) }
+ .rela.got : { *(.rela.got) }
+ .rela.data : { *(.rela.data) *(.rela.data*) }
+ . = ALIGN(512);
+ _edata = .;
+ _data_size = . - _data;
+
+ . = ALIGN(4096);
+ .dynsym : { *(.dynsym) }
+ . = ALIGN(4096);
+ .dynstr : { *(.dynstr) }
+ . = ALIGN(4096);
+ .note.gnu.build-id : { *(.note.gnu.build-id) }
+ /DISCARD/ :
+ {
+ *(.rel.reloc)
+ *(.eh_frame)
+ *(.note.GNU-stack)
+ }
+ .comment 0 : { *(.comment) }
+}
diff --git a/arm/efi/crt0-efi-aarch64.S b/arm/efi/crt0-efi-aarch64.S
new file mode 100644
index 00000000..d50e78dd
--- /dev/null
+++ b/arm/efi/crt0-efi-aarch64.S
@@ -0,0 +1,130 @@
+/*
+ * crt0-efi-aarch64.S - PE/COFF header for AArch64 EFI applications
+ *
+ * Copright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice and this list of conditions, without modification.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or (at your option) any later version.
+ */
+
+ .section .text.head
+
+ /*
+ * Magic "MZ" signature for PE/COFF
+ */
+ .globl ImageBase
+ImageBase:
+ .ascii "MZ"
+ .skip 58 // 'MZ' + pad + offset == 64
+ .long pe_header - ImageBase // Offset to the PE header.
+pe_header:
+ .ascii "PE"
+ .short 0
+coff_header:
+ .short 0xaa64 // AArch64
+ .short 2 // nr_sections
+ .long 0 // TimeDateStamp
+ .long 0 // PointerToSymbolTable
+ .long 0 // NumberOfSymbols
+ .short section_table - optional_header // SizeOfOptionalHeader
+ .short 0x206 // Characteristics.
+ // IMAGE_FILE_DEBUG_STRIPPED |
+ // IMAGE_FILE_EXECUTABLE_IMAGE |
+ // IMAGE_FILE_LINE_NUMS_STRIPPED
+optional_header:
+ .short 0x20b // PE32+ format
+ .byte 0x02 // MajorLinkerVersion
+ .byte 0x14 // MinorLinkerVersion
+ .long _data - _start // SizeOfCode
+ .long _data_size // SizeOfInitializedData
+ .long 0 // SizeOfUninitializedData
+ .long _start - ImageBase // AddressOfEntryPoint
+ .long _start - ImageBase // BaseOfCode
+
+extra_header_fields:
+ .quad 0 // ImageBase
+ .long 0x1000 // SectionAlignment
+ .long 0x200 // FileAlignment
+ .short 0 // MajorOperatingSystemVersion
+ .short 0 // MinorOperatingSystemVersion
+ .short 0 // MajorImageVersion
+ .short 0 // MinorImageVersion
+ .short 0 // MajorSubsystemVersion
+ .short 0 // MinorSubsystemVersion
+ .long 0 // Win32VersionValue
+
+ .long _edata - ImageBase // SizeOfImage
+
+ // Everything before the kernel image is considered part of the header
+ .long _start - ImageBase // SizeOfHeaders
+ .long 0 // CheckSum
+ .short EFI_SUBSYSTEM // Subsystem
+ .short 0 // DllCharacteristics
+ .quad 0 // SizeOfStackReserve
+ .quad 0 // SizeOfStackCommit
+ .quad 0 // SizeOfHeapReserve
+ .quad 0 // SizeOfHeapCommit
+ .long 0 // LoaderFlags
+ .long 0x6 // NumberOfRvaAndSizes
+
+ .quad 0 // ExportTable
+ .quad 0 // ImportTable
+ .quad 0 // ResourceTable
+ .quad 0 // ExceptionTable
+ .quad 0 // CertificationTable
+ .quad 0 // BaseRelocationTable
+
+ // Section table
+section_table:
+ .ascii ".text\0\0\0"
+ .long _data - _start // VirtualSize
+ .long _start - ImageBase // VirtualAddress
+ .long _data - _start // SizeOfRawData
+ .long _start - ImageBase // PointerToRawData
+
+ .long 0 // PointerToRelocations (0 for executables)
+ .long 0 // PointerToLineNumbers (0 for executables)
+ .short 0 // NumberOfRelocations (0 for executables)
+ .short 0 // NumberOfLineNumbers (0 for executables)
+ .long 0x60000020 // Characteristics (section flags)
+
+ .ascii ".data\0\0\0"
+ .long _data_size // VirtualSize
+ .long _data - ImageBase // VirtualAddress
+ .long _data_size // SizeOfRawData
+ .long _data - ImageBase // PointerToRawData
+
+ .long 0 // PointerToRelocations (0 for executables)
+ .long 0 // PointerToLineNumbers (0 for executables)
+ .short 0 // NumberOfRelocations (0 for executables)
+ .short 0 // NumberOfLineNumbers (0 for executables)
+ .long 0xc0000040 // Characteristics (section flags)
+
+ .align 12
+_start:
+ stp x29, x30, [sp, #-32]!
+ mov x29, sp
+
+ stp x0, x1, [sp, #16]
+ mov x2, x0
+ mov x3, x1
+ adr x0, ImageBase
+ adrp x1, _DYNAMIC
+ add x1, x1, #:lo12:_DYNAMIC
+ bl _relocate
+ cbnz x0, 0f
+
+ ldp x0, x1, [sp, #16]
+ bl efi_main
+
+0: ldp x29, x30, [sp], #32
+ ret
diff --git a/arm/efi/reloc_aarch64.c b/arm/efi/reloc_aarch64.c
new file mode 100644
index 00000000..08672796
--- /dev/null
+++ b/arm/efi/reloc_aarch64.c
@@ -0,0 +1,97 @@
+/* reloc_aarch64.c - position independent x86 ELF shared object relocator
+ Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
+ Copyright (C) 1999 Hewlett-Packard Co.
+ Contributed by David Mosberger <davidm@hpl.hp.com>.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+ * Neither the name of Hewlett-Packard Co. nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+*/
+
+#include <efi.h>
+#include <efilib.h>
+
+#include <elf.h>
+
+EFI_STATUS _relocate (long ldbase, Elf64_Dyn *dyn,
+ EFI_HANDLE image EFI_UNUSED,
+ EFI_SYSTEM_TABLE *systab EFI_UNUSED)
+{
+ long relsz = 0, relent = 0;
+ Elf64_Rela *rel = 0;
+ unsigned long *addr;
+ int i;
+
+ for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
+ switch (dyn[i].d_tag) {
+ case DT_RELA:
+ rel = (Elf64_Rela*)
+ ((unsigned long)dyn[i].d_un.d_ptr
+ + ldbase);
+ break;
+
+ case DT_RELASZ:
+ relsz = dyn[i].d_un.d_val;
+ break;
+
+ case DT_RELAENT:
+ relent = dyn[i].d_un.d_val;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (!rel && relent == 0)
+ return EFI_SUCCESS;
+
+ if (!rel || relent == 0)
+ return EFI_LOAD_ERROR;
+
+ while (relsz > 0) {
+ /* apply the relocs */
+ switch (ELF64_R_TYPE (rel->r_info)) {
+ case R_AARCH64_NONE:
+ break;
+
+ case R_AARCH64_RELATIVE:
+ addr = (unsigned long *)
+ (ldbase + rel->r_offset);
+ *addr = ldbase + rel->r_addend;
+ break;
+
+ default:
+ break;
+ }
+ rel = (Elf64_Rela*) ((char *) rel + relent);
+ relsz -= relent;
+ }
+ return EFI_SUCCESS;
+}
--
2.25.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [kvm-unit-tests PATCH v5 24/29] arm64: Change GNU-EFI imported code to use defined types
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
` (22 preceding siblings ...)
2023-04-28 12:03 ` [kvm-unit-tests PATCH v5 23/29] arm64: Copy code from GNU-EFI Nikos Nikoleris
@ 2023-04-28 12:04 ` Nikos Nikoleris
2023-04-28 12:04 ` [kvm-unit-tests PATCH v5 25/29] arm64: Use code from the gnu-efi when booting with EFI Nikos Nikoleris
` (6 subsequent siblings)
30 siblings, 0 replies; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-28 12:04 UTC (permalink / raw)
To: kvm, kvmarm, andrew.jones; +Cc: pbonzini, alexandru.elisei, ricarkol
Convert some types to avoid dependency on gnu-efi's <efi.h> and
<efilib.h>.
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
---
arm/efi/reloc_aarch64.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/arm/efi/reloc_aarch64.c b/arm/efi/reloc_aarch64.c
index 08672796..5ba0ba1f 100644
--- a/arm/efi/reloc_aarch64.c
+++ b/arm/efi/reloc_aarch64.c
@@ -35,13 +35,10 @@
*/
#include <efi.h>
-#include <efilib.h>
-
#include <elf.h>
-EFI_STATUS _relocate (long ldbase, Elf64_Dyn *dyn,
- EFI_HANDLE image EFI_UNUSED,
- EFI_SYSTEM_TABLE *systab EFI_UNUSED)
+efi_status_t _relocate(long ldbase, Elf64_Dyn *dyn, efi_handle_t image,
+ efi_system_table_t *sys_tab)
{
long relsz = 0, relent = 0;
Elf64_Rela *rel = 0;
--
2.25.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [kvm-unit-tests PATCH v5 25/29] arm64: Use code from the gnu-efi when booting with EFI
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
` (23 preceding siblings ...)
2023-04-28 12:04 ` [kvm-unit-tests PATCH v5 24/29] arm64: Change GNU-EFI imported code to use defined types Nikos Nikoleris
@ 2023-04-28 12:04 ` Nikos Nikoleris
2023-04-28 12:04 ` [kvm-unit-tests PATCH v5 26/29] lib: Avoid external dependency in libelf Nikos Nikoleris
` (5 subsequent siblings)
30 siblings, 0 replies; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-28 12:04 UTC (permalink / raw)
To: kvm, kvmarm, andrew.jones; +Cc: pbonzini, alexandru.elisei, ricarkol
arm/efi/crt0-efi-aarch64.S defines the header and the handover
sequence from EFI to a efi_main. This change includes the whole file
in arm/cstart64.S when we compile with EFI support.
In addition, we change the handover code in arm/efi/crt0-efi-aarch64.S
to align the stack pointer. This alignment is necessary because we
make assumptions about cpu0's stack alignment and most importantly we
place its thread_info at the bottom of this stack.
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
---
arm/cstart64.S | 6 ++++++
arm/efi/crt0-efi-aarch64.S | 19 +++++++++++++++----
2 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/arm/cstart64.S b/arm/cstart64.S
index 223c1092..cbd6b511 100644
--- a/arm/cstart64.S
+++ b/arm/cstart64.S
@@ -15,6 +15,10 @@
#include <asm/thread_info.h>
#include <asm/sysreg.h>
+#ifdef CONFIG_EFI
+#include "efi/crt0-efi-aarch64.S"
+#else
+
.macro zero_range, tmp1, tmp2
9998: cmp \tmp1, \tmp2
b.eq 9997f
@@ -107,6 +111,8 @@ start:
bl exit
b halt
+#endif
+
.text
/*
diff --git a/arm/efi/crt0-efi-aarch64.S b/arm/efi/crt0-efi-aarch64.S
index d50e78dd..5d0dc04a 100644
--- a/arm/efi/crt0-efi-aarch64.S
+++ b/arm/efi/crt0-efi-aarch64.S
@@ -111,10 +111,17 @@ section_table:
.align 12
_start:
- stp x29, x30, [sp, #-32]!
+ stp x29, x30, [sp, #-16]!
+
+ /* Align sp; this is necessary due to way we store cpu0's thread_info */
mov x29, sp
+ mov x30, sp
+ and x30, x30, #THREAD_MASK
+ mov sp, x30
+ str x29, [sp, #-16]!
+
+ stp x0, x1, [sp, #-16]!
- stp x0, x1, [sp, #16]
mov x2, x0
mov x3, x1
adr x0, ImageBase
@@ -123,8 +130,12 @@ _start:
bl _relocate
cbnz x0, 0f
- ldp x0, x1, [sp, #16]
+ ldp x0, x1, [sp], #16
bl efi_main
-0: ldp x29, x30, [sp], #32
+ /* Restore sp */
+ ldr x30, [sp], #16
+ mov sp, x30
+
+0: ldp x29, x30, [sp], #16
ret
--
2.25.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [kvm-unit-tests PATCH v5 26/29] lib: Avoid external dependency in libelf
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
` (24 preceding siblings ...)
2023-04-28 12:04 ` [kvm-unit-tests PATCH v5 25/29] arm64: Use code from the gnu-efi when booting with EFI Nikos Nikoleris
@ 2023-04-28 12:04 ` Nikos Nikoleris
2023-04-28 12:04 ` [kvm-unit-tests PATCH v5 27/29] arm64: Add support for efi in Makefile Nikos Nikoleris
` (4 subsequent siblings)
30 siblings, 0 replies; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-28 12:04 UTC (permalink / raw)
To: kvm, kvmarm, andrew.jones; +Cc: pbonzini, alexandru.elisei, ricarkol
There is just a small number of definitions we need from
uapi/linux/elf.h and asm/elf.h and the relocation code is
self-contained.
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Ricardo Koller <ricarkol@google.com>
---
lib/elf.h | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 57 insertions(+)
create mode 100644 lib/elf.h
diff --git a/lib/elf.h b/lib/elf.h
new file mode 100644
index 00000000..abd5cf4b
--- /dev/null
+++ b/lib/elf.h
@@ -0,0 +1,57 @@
+/* SPDX-License-Identifier: LGPL-2.0-or-later */
+/*
+ * Relevant definitions from uapi/linux/elf.h and asm/elf.h
+ */
+
+#ifndef _ELF_H_
+#define _ELF_H_
+
+#include <libcflat.h>
+
+/* 64-bit ELF base types. */
+typedef u64 Elf64_Addr;
+typedef u64 Elf64_Xword;
+typedef s64 Elf64_Sxword;
+
+typedef struct {
+ Elf64_Sxword d_tag; /* entry tag value */
+ union {
+ Elf64_Xword d_val;
+ Elf64_Addr d_ptr;
+ } d_un;
+} Elf64_Dyn;
+
+typedef struct elf64_rel {
+ Elf64_Addr r_offset; /* Location at which to apply the action */
+ Elf64_Xword r_info; /* index and type of relocation */
+} Elf64_Rel;
+
+typedef struct elf64_rela {
+ Elf64_Addr r_offset; /* Location at which to apply the action */
+ Elf64_Xword r_info; /* index and type of relocation */
+ Elf64_Sxword r_addend; /* Constant addend used to compute value */
+} Elf64_Rela;
+
+/* This is the info that is needed to parse the dynamic section of the file */
+#define DT_NULL 0
+#define DT_RELA 7
+#define DT_RELASZ 8
+#define DT_RELAENT 9
+
+/* x86 relocation types. */
+#define R_X86_64_NONE 0 /* No reloc */
+#define R_X86_64_RELATIVE 8 /* Adjust by program base */
+
+
+/*
+ * AArch64 static relocation types.
+ */
+
+/* Miscellaneous. */
+#define R_AARCH64_NONE 256
+#define R_AARCH64_RELATIVE 1027
+
+/* The following are used with relocations */
+#define ELF64_R_TYPE(i) ((i) & 0xffffffff)
+
+#endif /* _ELF_H_ */
--
2.25.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [kvm-unit-tests PATCH v5 27/29] arm64: Add support for efi in Makefile
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
` (25 preceding siblings ...)
2023-04-28 12:04 ` [kvm-unit-tests PATCH v5 26/29] lib: Avoid external dependency in libelf Nikos Nikoleris
@ 2023-04-28 12:04 ` Nikos Nikoleris
2023-05-01 13:00 ` Shaoqin Huang
2023-04-28 12:04 ` [kvm-unit-tests PATCH v5 28/29] lib: arm: Print test exit status Nikos Nikoleris
` (3 subsequent siblings)
30 siblings, 1 reply; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-28 12:04 UTC (permalink / raw)
To: kvm, kvmarm, andrew.jones; +Cc: pbonzini, alexandru.elisei, ricarkol
Users can now build kvm-unit-tests as efi apps by supplying an extra
argument when invoking configure:
$> ./configure --enable-efi
This patch is based on an earlier version by
Andrew Jones <drjones@redhat.com>
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Ricardo Koller <ricarkol@google.com>
---
configure | 17 +++++++++++++----
arm/Makefile.arm | 6 ++++++
arm/Makefile.arm64 | 18 ++++++++++++++----
arm/Makefile.common | 45 ++++++++++++++++++++++++++++++++++-----------
4 files changed, 67 insertions(+), 19 deletions(-)
diff --git a/configure b/configure
index c36fd290..b665f7d5 100755
--- a/configure
+++ b/configure
@@ -86,7 +86,7 @@ usage() {
pl011,mmio32,ADDR
Specify a PL011 compatible UART at address ADDR. Supported
register stride is 32 bit only.
- --[enable|disable]-efi Boot and run from UEFI (disabled by default, x86_64 only)
+ --[enable|disable]-efi Boot and run from UEFI (disabled by default, x86_64 and arm64 only)
--[enable|disable]-werror
Select whether to compile with the -Werror compiler flag
EOF
@@ -208,14 +208,19 @@ else
fi
fi
-if [ "$efi" ] && [ "$arch" != "x86_64" ]; then
+if [ "$efi" ] && [ "$arch" != "x86_64" ] && [ "$arch" != "arm64" ]; then
echo "--[enable|disable]-efi is not supported for $arch"
usage
fi
if [ -z "$page_size" ]; then
- [ "$arch" = "arm64" ] && page_size="65536"
- [ "$arch" = "arm" ] && page_size="4096"
+ if [ "$efi" = 'y' ] && [ "$arch" = "arm64" ]; then
+ page_size="4096"
+ elif [ "$arch" = "arm64" ]; then
+ page_size="65536"
+ elif [ "$arch" = "arm" ]; then
+ page_size="4096"
+ fi
else
if [ "$arch" != "arm64" ]; then
echo "--page-size is not supported for $arch"
@@ -230,6 +235,10 @@ else
echo "arm64 doesn't support page size of $page_size"
usage
fi
+ if [ "$efi" = 'y' ] && [ "$page_size" != "4096" ]; then
+ echo "efi must use 4K pages"
+ exit 1
+ fi
fi
[ -z "$processor" ] && processor="$arch"
diff --git a/arm/Makefile.arm b/arm/Makefile.arm
index 01fd4c7b..2ce00f52 100644
--- a/arm/Makefile.arm
+++ b/arm/Makefile.arm
@@ -7,6 +7,10 @@ bits = 32
ldarch = elf32-littlearm
machine = -marm -mfpu=vfp
+ifeq ($(CONFIG_EFI),y)
+$(error Cannot build arm32 tests as EFI apps)
+endif
+
# stack.o relies on frame pointers.
KEEP_FRAME_POINTER := y
@@ -32,6 +36,8 @@ cflatobjs += lib/arm/stack.o
cflatobjs += lib/ldiv32.o
cflatobjs += lib/arm/ldivmod.o
+exe = flat
+
# arm specific tests
tests =
diff --git a/arm/Makefile.arm64 b/arm/Makefile.arm64
index 6dff6cad..eada7f9a 100644
--- a/arm/Makefile.arm64
+++ b/arm/Makefile.arm64
@@ -31,11 +31,21 @@ endif
OBJDIRS += lib/arm64
+ifeq ($(CONFIG_EFI),y)
+# avoid jump tables before all relocations have been processed
+arm/efi/reloc_aarch64.o: CFLAGS += -fno-jump-tables
+cflatobjs += arm/efi/reloc_aarch64.o
+
+exe = efi
+else
+exe = flat
+endif
+
# arm64 specific tests
-tests = $(TEST_DIR)/timer.flat
-tests += $(TEST_DIR)/micro-bench.flat
-tests += $(TEST_DIR)/cache.flat
-tests += $(TEST_DIR)/debug.flat
+tests = $(TEST_DIR)/timer.$(exe)
+tests += $(TEST_DIR)/micro-bench.$(exe)
+tests += $(TEST_DIR)/cache.$(exe)
+tests += $(TEST_DIR)/debug.$(exe)
include $(SRCDIR)/$(TEST_DIR)/Makefile.common
diff --git a/arm/Makefile.common b/arm/Makefile.common
index 647b0fb1..a133309d 100644
--- a/arm/Makefile.common
+++ b/arm/Makefile.common
@@ -4,14 +4,14 @@
# Authors: Andrew Jones <drjones@redhat.com>
#
-tests-common = $(TEST_DIR)/selftest.flat
-tests-common += $(TEST_DIR)/spinlock-test.flat
-tests-common += $(TEST_DIR)/pci-test.flat
-tests-common += $(TEST_DIR)/pmu.flat
-tests-common += $(TEST_DIR)/gic.flat
-tests-common += $(TEST_DIR)/psci.flat
-tests-common += $(TEST_DIR)/sieve.flat
-tests-common += $(TEST_DIR)/pl031.flat
+tests-common = $(TEST_DIR)/selftest.$(exe)
+tests-common += $(TEST_DIR)/spinlock-test.$(exe)
+tests-common += $(TEST_DIR)/pci-test.$(exe)
+tests-common += $(TEST_DIR)/pmu.$(exe)
+tests-common += $(TEST_DIR)/gic.$(exe)
+tests-common += $(TEST_DIR)/psci.$(exe)
+tests-common += $(TEST_DIR)/sieve.$(exe)
+tests-common += $(TEST_DIR)/pl031.$(exe)
tests-all = $(tests-common) $(tests)
all: directories $(tests-all)
@@ -54,6 +54,9 @@ cflatobjs += lib/arm/smp.o
cflatobjs += lib/arm/delay.o
cflatobjs += lib/arm/gic.o lib/arm/gic-v2.o lib/arm/gic-v3.o
cflatobjs += lib/arm/timer.o
+ifeq ($(CONFIG_EFI),y)
+cflatobjs += lib/efi.o
+endif
OBJDIRS += lib/arm
@@ -61,6 +64,25 @@ libeabi = lib/arm/libeabi.a
eabiobjs = lib/arm/eabi_compat.o
FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libeabi)
+
+ifeq ($(CONFIG_EFI),y)
+%.so: EFI_LDFLAGS += -defsym=EFI_SUBSYSTEM=0xa --no-undefined
+%.so: %.o $(FLATLIBS) $(SRCDIR)/arm/efi/elf_aarch64_efi.lds $(cstart.o)
+ $(CC) $(CFLAGS) -c -o $(@:.so=.aux.o) $(SRCDIR)/lib/auxinfo.c \
+ -DPROGNAME=\"$(@:.so=.efi)\" -DAUXFLAGS=$(AUXFLAGS)
+ $(LD) $(EFI_LDFLAGS) -o $@ -T $(SRCDIR)/arm/efi/elf_aarch64_efi.lds \
+ $(filter %.o, $^) $(FLATLIBS) $(@:.so=.aux.o) \
+ $(EFI_LIBS)
+ $(RM) $(@:.so=.aux.o)
+
+%.efi: %.so
+ $(call arch_elf_check, $^)
+ $(OBJCOPY) \
+ -j .text -j .sdata -j .data -j .dynamic -j .dynsym \
+ -j .rel -j .rela -j .rel.* -j .rela.* -j .rel* -j .rela* \
+ -j .reloc \
+ -O binary $^ $@
+else
%.elf: LDFLAGS = -nostdlib $(arch_LDFLAGS)
%.elf: %.o $(FLATLIBS) $(SRCDIR)/arm/flat.lds $(cstart.o)
$(CC) $(CFLAGS) -c -o $(@:.elf=.aux.o) $(SRCDIR)/lib/auxinfo.c \
@@ -74,13 +96,14 @@ FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libeabi)
$(call arch_elf_check, $^)
$(OBJCOPY) -O binary $^ $@
@chmod a-x $@
+endif
$(libeabi): $(eabiobjs)
$(AR) rcs $@ $^
arm_clean: asm_offsets_clean
- $(RM) $(TEST_DIR)/*.{o,flat,elf} $(libeabi) $(eabiobjs) \
- $(TEST_DIR)/.*.d lib/arm/.*.d
+ $(RM) $(TEST_DIR)/*.{o,flat,elf,so,efi} $(libeabi) $(eabiobjs) \
+ $(TEST_DIR)/.*.d $(TEST_DIR)/efi/.*.d lib/arm/.*.d
generated-files = $(asm-offsets)
-$(tests-all:.flat=.o) $(cstart.o) $(cflatobjs): $(generated-files)
+$(tests-all:.$(exe)=.o) $(cstart.o) $(cflatobjs): $(generated-files)
--
2.25.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* Re: [kvm-unit-tests PATCH v5 27/29] arm64: Add support for efi in Makefile
2023-04-28 12:04 ` [kvm-unit-tests PATCH v5 27/29] arm64: Add support for efi in Makefile Nikos Nikoleris
@ 2023-05-01 13:00 ` Shaoqin Huang
0 siblings, 0 replies; 52+ messages in thread
From: Shaoqin Huang @ 2023-05-01 13:00 UTC (permalink / raw)
To: Nikos Nikoleris, kvm, kvmarm, andrew.jones
Cc: pbonzini, alexandru.elisei, ricarkol
On 4/28/23 20:04, Nikos Nikoleris wrote:
> Users can now build kvm-unit-tests as efi apps by supplying an extra
> argument when invoking configure:
>
> $> ./configure --enable-efi
>
> This patch is based on an earlier version by
> Andrew Jones <drjones@redhat.com>
>
> Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
> Reviewed-by: Ricardo Koller <ricarkol@google.com>
Reviewed-by: Shaoqin Huang <shahuang@redhat.com>
> ---
> configure | 17 +++++++++++++----
> arm/Makefile.arm | 6 ++++++
> arm/Makefile.arm64 | 18 ++++++++++++++----
> arm/Makefile.common | 45 ++++++++++++++++++++++++++++++++++-----------
> 4 files changed, 67 insertions(+), 19 deletions(-)
>
> diff --git a/configure b/configure
> index c36fd290..b665f7d5 100755
> --- a/configure
> +++ b/configure
> @@ -86,7 +86,7 @@ usage() {
> pl011,mmio32,ADDR
> Specify a PL011 compatible UART at address ADDR. Supported
> register stride is 32 bit only.
> - --[enable|disable]-efi Boot and run from UEFI (disabled by default, x86_64 only)
> + --[enable|disable]-efi Boot and run from UEFI (disabled by default, x86_64 and arm64 only)
> --[enable|disable]-werror
> Select whether to compile with the -Werror compiler flag
> EOF
> @@ -208,14 +208,19 @@ else
> fi
> fi
>
> -if [ "$efi" ] && [ "$arch" != "x86_64" ]; then
> +if [ "$efi" ] && [ "$arch" != "x86_64" ] && [ "$arch" != "arm64" ]; then
> echo "--[enable|disable]-efi is not supported for $arch"
> usage
> fi
>
> if [ -z "$page_size" ]; then
> - [ "$arch" = "arm64" ] && page_size="65536"
> - [ "$arch" = "arm" ] && page_size="4096"
> + if [ "$efi" = 'y' ] && [ "$arch" = "arm64" ]; then
> + page_size="4096"
> + elif [ "$arch" = "arm64" ]; then
> + page_size="65536"
> + elif [ "$arch" = "arm" ]; then
> + page_size="4096"
> + fi
> else
> if [ "$arch" != "arm64" ]; then
> echo "--page-size is not supported for $arch"
> @@ -230,6 +235,10 @@ else
> echo "arm64 doesn't support page size of $page_size"
> usage
> fi
> + if [ "$efi" = 'y' ] && [ "$page_size" != "4096" ]; then
> + echo "efi must use 4K pages"
> + exit 1
> + fi
> fi
>
> [ -z "$processor" ] && processor="$arch"
> diff --git a/arm/Makefile.arm b/arm/Makefile.arm
> index 01fd4c7b..2ce00f52 100644
> --- a/arm/Makefile.arm
> +++ b/arm/Makefile.arm
> @@ -7,6 +7,10 @@ bits = 32
> ldarch = elf32-littlearm
> machine = -marm -mfpu=vfp
>
> +ifeq ($(CONFIG_EFI),y)
> +$(error Cannot build arm32 tests as EFI apps)
> +endif
> +
> # stack.o relies on frame pointers.
> KEEP_FRAME_POINTER := y
>
> @@ -32,6 +36,8 @@ cflatobjs += lib/arm/stack.o
> cflatobjs += lib/ldiv32.o
> cflatobjs += lib/arm/ldivmod.o
>
> +exe = flat
> +
> # arm specific tests
> tests =
>
> diff --git a/arm/Makefile.arm64 b/arm/Makefile.arm64
> index 6dff6cad..eada7f9a 100644
> --- a/arm/Makefile.arm64
> +++ b/arm/Makefile.arm64
> @@ -31,11 +31,21 @@ endif
>
> OBJDIRS += lib/arm64
>
> +ifeq ($(CONFIG_EFI),y)
> +# avoid jump tables before all relocations have been processed
> +arm/efi/reloc_aarch64.o: CFLAGS += -fno-jump-tables
> +cflatobjs += arm/efi/reloc_aarch64.o
> +
> +exe = efi
> +else
> +exe = flat
> +endif
> +
> # arm64 specific tests
> -tests = $(TEST_DIR)/timer.flat
> -tests += $(TEST_DIR)/micro-bench.flat
> -tests += $(TEST_DIR)/cache.flat
> -tests += $(TEST_DIR)/debug.flat
> +tests = $(TEST_DIR)/timer.$(exe)
> +tests += $(TEST_DIR)/micro-bench.$(exe)
> +tests += $(TEST_DIR)/cache.$(exe)
> +tests += $(TEST_DIR)/debug.$(exe)
>
> include $(SRCDIR)/$(TEST_DIR)/Makefile.common
>
> diff --git a/arm/Makefile.common b/arm/Makefile.common
> index 647b0fb1..a133309d 100644
> --- a/arm/Makefile.common
> +++ b/arm/Makefile.common
> @@ -4,14 +4,14 @@
> # Authors: Andrew Jones <drjones@redhat.com>
> #
>
> -tests-common = $(TEST_DIR)/selftest.flat
> -tests-common += $(TEST_DIR)/spinlock-test.flat
> -tests-common += $(TEST_DIR)/pci-test.flat
> -tests-common += $(TEST_DIR)/pmu.flat
> -tests-common += $(TEST_DIR)/gic.flat
> -tests-common += $(TEST_DIR)/psci.flat
> -tests-common += $(TEST_DIR)/sieve.flat
> -tests-common += $(TEST_DIR)/pl031.flat
> +tests-common = $(TEST_DIR)/selftest.$(exe)
> +tests-common += $(TEST_DIR)/spinlock-test.$(exe)
> +tests-common += $(TEST_DIR)/pci-test.$(exe)
> +tests-common += $(TEST_DIR)/pmu.$(exe)
> +tests-common += $(TEST_DIR)/gic.$(exe)
> +tests-common += $(TEST_DIR)/psci.$(exe)
> +tests-common += $(TEST_DIR)/sieve.$(exe)
> +tests-common += $(TEST_DIR)/pl031.$(exe)
>
> tests-all = $(tests-common) $(tests)
> all: directories $(tests-all)
> @@ -54,6 +54,9 @@ cflatobjs += lib/arm/smp.o
> cflatobjs += lib/arm/delay.o
> cflatobjs += lib/arm/gic.o lib/arm/gic-v2.o lib/arm/gic-v3.o
> cflatobjs += lib/arm/timer.o
> +ifeq ($(CONFIG_EFI),y)
> +cflatobjs += lib/efi.o
> +endif
>
> OBJDIRS += lib/arm
>
> @@ -61,6 +64,25 @@ libeabi = lib/arm/libeabi.a
> eabiobjs = lib/arm/eabi_compat.o
>
> FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libeabi)
> +
> +ifeq ($(CONFIG_EFI),y)
> +%.so: EFI_LDFLAGS += -defsym=EFI_SUBSYSTEM=0xa --no-undefined
> +%.so: %.o $(FLATLIBS) $(SRCDIR)/arm/efi/elf_aarch64_efi.lds $(cstart.o)
> + $(CC) $(CFLAGS) -c -o $(@:.so=.aux.o) $(SRCDIR)/lib/auxinfo.c \
> + -DPROGNAME=\"$(@:.so=.efi)\" -DAUXFLAGS=$(AUXFLAGS)
> + $(LD) $(EFI_LDFLAGS) -o $@ -T $(SRCDIR)/arm/efi/elf_aarch64_efi.lds \
> + $(filter %.o, $^) $(FLATLIBS) $(@:.so=.aux.o) \
> + $(EFI_LIBS)
> + $(RM) $(@:.so=.aux.o)
> +
> +%.efi: %.so
> + $(call arch_elf_check, $^)
> + $(OBJCOPY) \
> + -j .text -j .sdata -j .data -j .dynamic -j .dynsym \
> + -j .rel -j .rela -j .rel.* -j .rela.* -j .rel* -j .rela* \
> + -j .reloc \
> + -O binary $^ $@
> +else
> %.elf: LDFLAGS = -nostdlib $(arch_LDFLAGS)
> %.elf: %.o $(FLATLIBS) $(SRCDIR)/arm/flat.lds $(cstart.o)
> $(CC) $(CFLAGS) -c -o $(@:.elf=.aux.o) $(SRCDIR)/lib/auxinfo.c \
> @@ -74,13 +96,14 @@ FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libeabi)
> $(call arch_elf_check, $^)
> $(OBJCOPY) -O binary $^ $@
> @chmod a-x $@
> +endif
>
> $(libeabi): $(eabiobjs)
> $(AR) rcs $@ $^
>
> arm_clean: asm_offsets_clean
> - $(RM) $(TEST_DIR)/*.{o,flat,elf} $(libeabi) $(eabiobjs) \
> - $(TEST_DIR)/.*.d lib/arm/.*.d
> + $(RM) $(TEST_DIR)/*.{o,flat,elf,so,efi} $(libeabi) $(eabiobjs) \
> + $(TEST_DIR)/.*.d $(TEST_DIR)/efi/.*.d lib/arm/.*.d
>
> generated-files = $(asm-offsets)
> -$(tests-all:.flat=.o) $(cstart.o) $(cflatobjs): $(generated-files)
> +$(tests-all:.$(exe)=.o) $(cstart.o) $(cflatobjs): $(generated-files)
--
Shaoqin
^ permalink raw reply [flat|nested] 52+ messages in thread
* [kvm-unit-tests PATCH v5 28/29] lib: arm: Print test exit status
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
` (26 preceding siblings ...)
2023-04-28 12:04 ` [kvm-unit-tests PATCH v5 27/29] arm64: Add support for efi in Makefile Nikos Nikoleris
@ 2023-04-28 12:04 ` Nikos Nikoleris
2023-05-01 13:00 ` Shaoqin Huang
2023-04-28 12:04 ` [kvm-unit-tests PATCH v5 29/29] arm64: Add an efi/run script Nikos Nikoleris
` (2 subsequent siblings)
30 siblings, 1 reply; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-28 12:04 UTC (permalink / raw)
To: kvm, kvmarm, andrew.jones; +Cc: Alexandru Elisei, pbonzini, ricarkol
From: Alexandru Elisei <alexandru.elisei@arm.com>
The arm tests can be run under kvmtool, which doesn't emulate a chr-testdev
device. Print the test exit status to make it possible for the runner
scripts to pick it up when they have support for it.
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Andrew Jones <andrew.jones@linux.dev>
---
lib/arm/io.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/lib/arm/io.c b/lib/arm/io.c
index 19f93490..c15e57c4 100644
--- a/lib/arm/io.c
+++ b/lib/arm/io.c
@@ -149,6 +149,13 @@ extern void halt(int code);
void exit(int code)
{
+ /*
+ * Print the test return code in the following format which is
+ * consistent with powerpc and s390x. The runner can pick it
+ * up when chr-testdev is not present.
+ */
+ printf("\nEXIT: STATUS=%d\n", ((code) << 1) | 1);
+
chr_testdev_exit(code);
psci_system_off();
halt(code);
--
2.25.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* Re: [kvm-unit-tests PATCH v5 28/29] lib: arm: Print test exit status
2023-04-28 12:04 ` [kvm-unit-tests PATCH v5 28/29] lib: arm: Print test exit status Nikos Nikoleris
@ 2023-05-01 13:00 ` Shaoqin Huang
0 siblings, 0 replies; 52+ messages in thread
From: Shaoqin Huang @ 2023-05-01 13:00 UTC (permalink / raw)
To: Nikos Nikoleris, kvm, kvmarm, andrew.jones
Cc: Alexandru Elisei, pbonzini, ricarkol
On 4/28/23 20:04, Nikos Nikoleris wrote:
> From: Alexandru Elisei <alexandru.elisei@arm.com>
>
> The arm tests can be run under kvmtool, which doesn't emulate a chr-testdev
> device. Print the test exit status to make it possible for the runner
> scripts to pick it up when they have support for it.
>
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
> Reviewed-by: Andrew Jones <andrew.jones@linux.dev>
Reviewed-by: Shaoqin Huang <shahuang@redhat.com>
> ---
> lib/arm/io.c | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/lib/arm/io.c b/lib/arm/io.c
> index 19f93490..c15e57c4 100644
> --- a/lib/arm/io.c
> +++ b/lib/arm/io.c
> @@ -149,6 +149,13 @@ extern void halt(int code);
>
> void exit(int code)
> {
> + /*
> + * Print the test return code in the following format which is
> + * consistent with powerpc and s390x. The runner can pick it
> + * up when chr-testdev is not present.
> + */
> + printf("\nEXIT: STATUS=%d\n", ((code) << 1) | 1);
> +
> chr_testdev_exit(code);
> psci_system_off();
> halt(code);
--
Shaoqin
^ permalink raw reply [flat|nested] 52+ messages in thread
* [kvm-unit-tests PATCH v5 29/29] arm64: Add an efi/run script
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
` (27 preceding siblings ...)
2023-04-28 12:04 ` [kvm-unit-tests PATCH v5 28/29] lib: arm: Print test exit status Nikos Nikoleris
@ 2023-04-28 12:04 ` Nikos Nikoleris
2023-05-01 12:48 ` Shaoqin Huang
2023-04-29 16:18 ` [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Andrew Jones
2023-05-01 12:09 ` Shaoqin Huang
30 siblings, 1 reply; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-28 12:04 UTC (permalink / raw)
To: kvm, kvmarm, andrew.jones; +Cc: pbonzini, alexandru.elisei, ricarkol
This change adds a efi/run script inspired by the one in x86. This
script will setup a folder with the test compiled as an EFI app and a
startup.nsh script. The script launches QEMU providing an image with
EDKII and the path to the folder with the test which is executed
automatically.
For example:
$> ./arm/efi/run ./arm/selftest.efi -append "setup smp=2 mem=256" -smp 2 -m 256
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Ricardo Koller <ricarkol@google.com>
---
scripts/runtime.bash | 13 +++++++---
arm/efi/run | 61 ++++++++++++++++++++++++++++++++++++++++++++
arm/run | 14 +++++++---
arm/Makefile.common | 1 +
arm/dummy.c | 12 +++++++++
5 files changed, 94 insertions(+), 7 deletions(-)
create mode 100755 arm/efi/run
create mode 100644 arm/dummy.c
diff --git a/scripts/runtime.bash b/scripts/runtime.bash
index 07b62b0e..785a7b62 100644
--- a/scripts/runtime.bash
+++ b/scripts/runtime.bash
@@ -130,11 +130,18 @@ function run()
done
fi
- last_line=$(premature_failure > >(tail -1)) && {
+ log=$(premature_failure) && {
skip=true
- if [ "${CONFIG_EFI}" == "y" ] && [[ "${last_line}" =~ "Dummy Hello World!" ]]; then
- skip=false
+ if [ "${CONFIG_EFI}" == "y" ]; then
+ if [ "$ARCH" == "x86_64" ] &&
+ [[ "$(tail -1 <<<"$log")" =~ "Dummy Hello World!" ]]; then
+ skip=false
+ elif [ "$ARCH" == "arm64" ] &&
+ [[ "$(tail -2 <<<"$log" | head -1)" =~ "Dummy Hello World!" ]]; then
+ skip=false
+ fi
fi
+
if [ ${skip} == true ]; then
print_result "SKIP" $testname "" "$last_line"
return 77
diff --git a/arm/efi/run b/arm/efi/run
new file mode 100755
index 00000000..dfff717a
--- /dev/null
+++ b/arm/efi/run
@@ -0,0 +1,61 @@
+#!/bin/bash
+
+set -e
+
+if [ $# -eq 0 ]; then
+ echo "Usage $0 TEST_CASE [QEMU_ARGS]"
+ exit 2
+fi
+
+if [ ! -f config.mak ]; then
+ echo "run './configure --enable-efi && make' first. See ./configure -h"
+ exit 2
+fi
+source config.mak
+source scripts/arch-run.bash
+source scripts/common.bash
+
+: "${EFI_SRC:=$(realpath "$(dirname "$0")/../")}"
+: "${EFI_UEFI:=/usr/share/qemu-efi-aarch64/QEMU_EFI.fd}"
+: "${EFI_TEST:=efi-tests}"
+: "${EFI_CASE:=$(basename $1 .efi)}"
+
+if [ ! -f "$EFI_UEFI" ]; then
+ echo "UEFI firmware not found: $EFI_UEFI"
+ echo "Please install the UEFI firmware to this path"
+ echo "Or specify the correct path with the env variable EFI_UEFI"
+ exit 2
+fi
+
+# Remove the TEST_CASE from $@
+shift 1
+
+# Fish out the arguments for the test, they should be the next string
+# after the "-append" option
+qemu_args=()
+cmd_args=()
+while (( "$#" )); do
+ if [ "$1" = "-append" ]; then
+ cmd_args=$2
+ shift 2
+ else
+ qemu_args+=("$1")
+ shift 1
+ fi
+done
+
+if [ "$EFI_CASE" = "_NO_FILE_4Uhere_" ]; then
+ EFI_CASE=dummy
+fi
+
+: "${EFI_CASE_DIR:="$EFI_TEST/$EFI_CASE"}"
+mkdir -p "$EFI_CASE_DIR"
+
+cp "$EFI_SRC/$EFI_CASE.efi" "$EFI_TEST/$EFI_CASE/"
+echo "@echo -off" > "$EFI_TEST/$EFI_CASE/startup.nsh"
+echo "$EFI_CASE.efi" "${cmd_args[@]}" >> "$EFI_TEST/$EFI_CASE/startup.nsh"
+
+EFI_RUN=y $TEST_DIR/run \
+ -bios "$EFI_UEFI" \
+ -drive file.dir="$EFI_TEST/$EFI_CASE/",file.driver=vvfat,file.rw=on,format=raw,if=virtio \
+ "${qemu_args[@]}"
diff --git a/arm/run b/arm/run
index c6f25b8c..de520c11 100755
--- a/arm/run
+++ b/arm/run
@@ -64,8 +64,10 @@ if ! $qemu $M -chardev '?' | grep -q testdev; then
exit 2
fi
-chr_testdev='-device virtio-serial-device'
-chr_testdev+=' -device virtconsole,chardev=ctd -chardev testdev,id=ctd'
+if [ "$EFI_RUN" != "y" ]; then
+ chr_testdev='-device virtio-serial-device'
+ chr_testdev+=' -device virtconsole,chardev=ctd -chardev testdev,id=ctd'
+fi
pci_testdev=
if $qemu $M -device '?' | grep -q pci-testdev; then
@@ -74,7 +76,11 @@ fi
A="-accel $ACCEL"
command="$qemu -nodefaults $M $A -cpu $processor $chr_testdev $pci_testdev"
-command+=" -display none -serial stdio -kernel"
+command+=" -display none -serial stdio"
command="$(migration_cmd) $(timeout_cmd) $command"
-run_qemu $command "$@"
+if [ "$EFI_RUN" = "y" ]; then
+ ENVIRON_DEFAULT=n run_qemu_status $command "$@"
+else
+ run_qemu $command -kernel "$@"
+fi
diff --git a/arm/Makefile.common b/arm/Makefile.common
index a133309d..d60cf8cd 100644
--- a/arm/Makefile.common
+++ b/arm/Makefile.common
@@ -12,6 +12,7 @@ tests-common += $(TEST_DIR)/gic.$(exe)
tests-common += $(TEST_DIR)/psci.$(exe)
tests-common += $(TEST_DIR)/sieve.$(exe)
tests-common += $(TEST_DIR)/pl031.$(exe)
+tests-common += $(TEST_DIR)/dummy.$(exe)
tests-all = $(tests-common) $(tests)
all: directories $(tests-all)
diff --git a/arm/dummy.c b/arm/dummy.c
new file mode 100644
index 00000000..7033bb7c
--- /dev/null
+++ b/arm/dummy.c
@@ -0,0 +1,12 @@
+#include "libcflat.h"
+
+int main(int argc, char **argv)
+{
+ /*
+ * scripts/runtime.bash uses this test as a canary to determine if the
+ * basic setup is functional. Print a magic string to let runtime.bash
+ * know that all is well.
+ */
+ printf("Dummy Hello World!");
+ return 0;
+}
--
2.25.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* Re: [kvm-unit-tests PATCH v5 29/29] arm64: Add an efi/run script
2023-04-28 12:04 ` [kvm-unit-tests PATCH v5 29/29] arm64: Add an efi/run script Nikos Nikoleris
@ 2023-05-01 12:48 ` Shaoqin Huang
0 siblings, 0 replies; 52+ messages in thread
From: Shaoqin Huang @ 2023-05-01 12:48 UTC (permalink / raw)
To: Nikos Nikoleris, kvm, kvmarm, andrew.jones
Cc: pbonzini, alexandru.elisei, ricarkol
Currently, it seems not support:
./run_test.sh -j8
Since different test will write the startup.nsh to the same directory,
which will make something wrong.
But that's fine right now. We can improve it later.
On 4/28/23 20:04, Nikos Nikoleris wrote:
> This change adds a efi/run script inspired by the one in x86. This
> script will setup a folder with the test compiled as an EFI app and a
> startup.nsh script. The script launches QEMU providing an image with
> EDKII and the path to the folder with the test which is executed
> automatically.
>
> For example:
>
> $> ./arm/efi/run ./arm/selftest.efi -append "setup smp=2 mem=256" -smp 2 -m 256
>
> Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
> Reviewed-by: Ricardo Koller <ricarkol@google.com>
Reviewed-by: Shaoqin Huang <shahuang@redhat.com>
> ---
> scripts/runtime.bash | 13 +++++++---
> arm/efi/run | 61 ++++++++++++++++++++++++++++++++++++++++++++
> arm/run | 14 +++++++---
> arm/Makefile.common | 1 +
> arm/dummy.c | 12 +++++++++
> 5 files changed, 94 insertions(+), 7 deletions(-)
> create mode 100755 arm/efi/run
> create mode 100644 arm/dummy.c
>
> diff --git a/scripts/runtime.bash b/scripts/runtime.bash
> index 07b62b0e..785a7b62 100644
> --- a/scripts/runtime.bash
> +++ b/scripts/runtime.bash
> @@ -130,11 +130,18 @@ function run()
> done
> fi
>
> - last_line=$(premature_failure > >(tail -1)) && {
> + log=$(premature_failure) && {
> skip=true
> - if [ "${CONFIG_EFI}" == "y" ] && [[ "${last_line}" =~ "Dummy Hello World!" ]]; then
> - skip=false
> + if [ "${CONFIG_EFI}" == "y" ]; then
> + if [ "$ARCH" == "x86_64" ] &&
> + [[ "$(tail -1 <<<"$log")" =~ "Dummy Hello World!" ]]; then
> + skip=false
> + elif [ "$ARCH" == "arm64" ] &&
> + [[ "$(tail -2 <<<"$log" | head -1)" =~ "Dummy Hello World!" ]]; then
> + skip=false
> + fi
> fi
> +
> if [ ${skip} == true ]; then
> print_result "SKIP" $testname "" "$last_line"
> return 77
> diff --git a/arm/efi/run b/arm/efi/run
> new file mode 100755
> index 00000000..dfff717a
> --- /dev/null
> +++ b/arm/efi/run
> @@ -0,0 +1,61 @@
> +#!/bin/bash
> +
> +set -e
> +
> +if [ $# -eq 0 ]; then
> + echo "Usage $0 TEST_CASE [QEMU_ARGS]"
> + exit 2
> +fi
> +
> +if [ ! -f config.mak ]; then
> + echo "run './configure --enable-efi && make' first. See ./configure -h"
> + exit 2
> +fi
> +source config.mak
> +source scripts/arch-run.bash
> +source scripts/common.bash
> +
> +: "${EFI_SRC:=$(realpath "$(dirname "$0")/../")}"
> +: "${EFI_UEFI:=/usr/share/qemu-efi-aarch64/QEMU_EFI.fd}"
> +: "${EFI_TEST:=efi-tests}"
> +: "${EFI_CASE:=$(basename $1 .efi)}"
> +
> +if [ ! -f "$EFI_UEFI" ]; then
> + echo "UEFI firmware not found: $EFI_UEFI"
> + echo "Please install the UEFI firmware to this path"
> + echo "Or specify the correct path with the env variable EFI_UEFI"
> + exit 2
> +fi
> +
> +# Remove the TEST_CASE from $@
> +shift 1
> +
> +# Fish out the arguments for the test, they should be the next string
> +# after the "-append" option
> +qemu_args=()
> +cmd_args=()
> +while (( "$#" )); do
> + if [ "$1" = "-append" ]; then
> + cmd_args=$2
> + shift 2
> + else
> + qemu_args+=("$1")
> + shift 1
> + fi
> +done
> +
> +if [ "$EFI_CASE" = "_NO_FILE_4Uhere_" ]; then
> + EFI_CASE=dummy
> +fi
> +
> +: "${EFI_CASE_DIR:="$EFI_TEST/$EFI_CASE"}"
> +mkdir -p "$EFI_CASE_DIR"
> +
> +cp "$EFI_SRC/$EFI_CASE.efi" "$EFI_TEST/$EFI_CASE/"
> +echo "@echo -off" > "$EFI_TEST/$EFI_CASE/startup.nsh"
> +echo "$EFI_CASE.efi" "${cmd_args[@]}" >> "$EFI_TEST/$EFI_CASE/startup.nsh"
> +
> +EFI_RUN=y $TEST_DIR/run \
> + -bios "$EFI_UEFI" \
> + -drive file.dir="$EFI_TEST/$EFI_CASE/",file.driver=vvfat,file.rw=on,format=raw,if=virtio \
> + "${qemu_args[@]}"
> diff --git a/arm/run b/arm/run
> index c6f25b8c..de520c11 100755
> --- a/arm/run
> +++ b/arm/run
> @@ -64,8 +64,10 @@ if ! $qemu $M -chardev '?' | grep -q testdev; then
> exit 2
> fi
>
> -chr_testdev='-device virtio-serial-device'
> -chr_testdev+=' -device virtconsole,chardev=ctd -chardev testdev,id=ctd'
> +if [ "$EFI_RUN" != "y" ]; then
> + chr_testdev='-device virtio-serial-device'
> + chr_testdev+=' -device virtconsole,chardev=ctd -chardev testdev,id=ctd'
> +fi
>
> pci_testdev=
> if $qemu $M -device '?' | grep -q pci-testdev; then
> @@ -74,7 +76,11 @@ fi
>
> A="-accel $ACCEL"
> command="$qemu -nodefaults $M $A -cpu $processor $chr_testdev $pci_testdev"
> -command+=" -display none -serial stdio -kernel"
> +command+=" -display none -serial stdio"
> command="$(migration_cmd) $(timeout_cmd) $command"
>
> -run_qemu $command "$@"
> +if [ "$EFI_RUN" = "y" ]; then
> + ENVIRON_DEFAULT=n run_qemu_status $command "$@"
> +else
> + run_qemu $command -kernel "$@"
> +fi
> diff --git a/arm/Makefile.common b/arm/Makefile.common
> index a133309d..d60cf8cd 100644
> --- a/arm/Makefile.common
> +++ b/arm/Makefile.common
> @@ -12,6 +12,7 @@ tests-common += $(TEST_DIR)/gic.$(exe)
> tests-common += $(TEST_DIR)/psci.$(exe)
> tests-common += $(TEST_DIR)/sieve.$(exe)
> tests-common += $(TEST_DIR)/pl031.$(exe)
> +tests-common += $(TEST_DIR)/dummy.$(exe)
>
> tests-all = $(tests-common) $(tests)
> all: directories $(tests-all)
> diff --git a/arm/dummy.c b/arm/dummy.c
> new file mode 100644
> index 00000000..7033bb7c
> --- /dev/null
> +++ b/arm/dummy.c
> @@ -0,0 +1,12 @@
> +#include "libcflat.h"
> +
> +int main(int argc, char **argv)
> +{
> + /*
> + * scripts/runtime.bash uses this test as a canary to determine if the
> + * basic setup is functional. Print a magic string to let runtime.bash
> + * know that all is well.
> + */
> + printf("Dummy Hello World!");
> + return 0;
> +}
--
Shaoqin
^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
` (28 preceding siblings ...)
2023-04-28 12:04 ` [kvm-unit-tests PATCH v5 29/29] arm64: Add an efi/run script Nikos Nikoleris
@ 2023-04-29 16:18 ` Andrew Jones
2023-04-29 16:21 ` Andrew Jones
2023-05-01 12:09 ` Shaoqin Huang
30 siblings, 1 reply; 52+ messages in thread
From: Andrew Jones @ 2023-04-29 16:18 UTC (permalink / raw)
To: Nikos Nikoleris; +Cc: kvm, kvmarm, pbonzini, alexandru.elisei, ricarkol, seanjc
On Fri, Apr 28, 2023 at 01:03:36PM +0100, Nikos Nikoleris wrote:
> Hello,
>
> This series adds initial support for building arm64 tests as EFI
> apps and running them under QEMU. Much like x86_64, we import external
> dependencies from gnu-efi and adapt them to work with types and other
> assumptions from kvm-unit-tests. In addition, this series adds support
> for enumerating parts of the system using ACPI.
>
> The first set of patches, moves the existing ACPI code to the common
> lib path. Then, it extends definitions and functions to allow for more
> robust discovery of ACPI tables. We add support for setting up the PSCI
> conduit, discovering the UART, timers, GIC and cpus via ACPI. The code
> retains existing behavior and gives priority to discovery through DT
> when one has been provided.
>
> In the second set of patches, we add support for getting the command
> line from the EFI shell. This is a requirement for many of the
> existing arm64 tests.
>
> In the third set of patches, we import code from gnu-efi, make minor
> changes and add an alternative setup sequence from arm64 systems that
> boot through EFI. Finally, we add support in the build system and a
> run script which is used to run an EFI app.
>
> After this set of patches one can build arm64 EFI tests:
>
> $> ./configure --enable-efi
> $> make
>
> And use the run script to run an EFI tests:
>
> $> ./arm/efi/run ./arm/selftest.efi -smp 2 -m 256 -append "setup smp=2 mem=256"
>
> Or all tests:
>
> $> ./run_tests.sh
>
> There are a few items that this series does not address but they would
> be useful to have:
> - Support for booting the system from EL2. Currently, we assume that a
> test starts EL1. This will be required to run EFI tests on sytems
> that implement EL2.
> - Support for reading environment variables and populating __envp.
> - Support for discovering the PCI subsystem using ACPI.
> - Get rid of other assumptions (e.g., vmalloc area) that don't hold on
> real HW.
> - Various fixes related to cache maintaince to better support turn the
> MMU off.
> - Switch to a new stack and avoid relying on the one provided by EFI.
>
> git branch: https://github.com/relokin/kvm-unit-tests/pull/new/target-efi-upstream-v5
>
> v4: https://lore.kernel.org/kvmarm/20230213101759.2577077-1-nikos.nikoleris@arm.com/
> v3: https://lore.kernel.org/all/20220630100324.3153655-1-nikos.nikoleris@arm.com/
> v2: https://lore.kernel.org/kvm/20220506205605.359830-1-nikos.nikoleris@arm.com/
>
> Changes in v5:
> - Minor style changes (thanks Shaoqin).
> - Avoid including lib/acpi.o to cflatobjs twice (thanks Drew).
> - Increase NR_INITIAL_MEM_REGIONS to avoid overflows and add check when
> we run out of space (thanks Shaoqin).
>
> Changes in v4:
> - Removed patch that reworks cache maintenance when turning the MMU
> off. This is not strictly required for EFI tests running with tcg and
> will be addressed in a separate series by Alex.
> - Fix compilation for arm (Alex).
> - Convert ACPI tables to Linux style (Alex).
>
> Changes in v3:
> - Addressed feedback from Drew, Alex and Ricardo. Many thanks for the reviews!
> - Added support for discovering the GIC through ACPI
> - Added a missing header file (<elf.h>)
> - Added support for correctly parsing the outcome of tests (./run_tests)
>
Thanks, Nikos!
I'd like to get an ack from either Paolo or Sean on the changes to ACPI,
as they're shared with x86, and there are also some x86 code changes.
Also,
1) It'd be nice if this worked with DT, too. We can use UEFI with DT
when adding '-no-acpi' to the QEMU command line. setup_efi() needs
to learn how to find the dtb and most the '#ifdef CONFIG_EFI's
would need to change to a new CONFIG_ACPI guard.
2) The debug bp and ss tests fail with EFI, but not without, for me.
3) The timer test runs (and succeeds) when run with
'./arm/efi/run ./arm/timer.efi', but not when run with
'./run_tests.sh -g timer'. This is because UEFI takes
up all the given timeout time (10s), and then the test times out.
The hackyish fix below resolves it for me. I'll consider posting it
as a real patch
Thanks,
drew
diff --git a/scripts/arch-run.bash b/scripts/arch-run.bash
index 51e4b97b27d1..72ce718b1170 100644
--- a/scripts/arch-run.bash
+++ b/scripts/arch-run.bash
@@ -94,7 +94,17 @@ run_qemu_status ()
timeout_cmd ()
{
+ local s
+
if [ "$TIMEOUT" ] && [ "$TIMEOUT" != "0" ]; then
+ if [ "$CONFIG_EFI" = 'y' ]; then
+ s=${TIMEOUT: -1}
+ if [ "$s" = 's' ]; then
+ TIMEOUT=${TIMEOUT:0:-1}
+ ((TIMEOUT += 10)) # Add 10 seconds for booting UEFI
+ TIMEOUT="${TIMEOUT}s"
+ fi
+ fi
echo "timeout -k 1s --foreground $TIMEOUT"
fi
}
^ permalink raw reply related [flat|nested] 52+ messages in thread* Re: [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64
2023-04-29 16:18 ` [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Andrew Jones
@ 2023-04-29 16:21 ` Andrew Jones
2023-04-30 0:02 ` Nikos Nikoleris
0 siblings, 1 reply; 52+ messages in thread
From: Andrew Jones @ 2023-04-29 16:21 UTC (permalink / raw)
To: Nikos Nikoleris; +Cc: kvm, kvmarm, pbonzini, alexandru.elisei, ricarkol, seanjc
On Sat, Apr 29, 2023 at 06:18:25PM +0200, Andrew Jones wrote:
> On Fri, Apr 28, 2023 at 01:03:36PM +0100, Nikos Nikoleris wrote:
> > Hello,
> >
> > This series adds initial support for building arm64 tests as EFI
> > apps and running them under QEMU. Much like x86_64, we import external
> > dependencies from gnu-efi and adapt them to work with types and other
> > assumptions from kvm-unit-tests. In addition, this series adds support
> > for enumerating parts of the system using ACPI.
> >
> > The first set of patches, moves the existing ACPI code to the common
> > lib path. Then, it extends definitions and functions to allow for more
> > robust discovery of ACPI tables. We add support for setting up the PSCI
> > conduit, discovering the UART, timers, GIC and cpus via ACPI. The code
> > retains existing behavior and gives priority to discovery through DT
> > when one has been provided.
> >
> > In the second set of patches, we add support for getting the command
> > line from the EFI shell. This is a requirement for many of the
> > existing arm64 tests.
> >
> > In the third set of patches, we import code from gnu-efi, make minor
> > changes and add an alternative setup sequence from arm64 systems that
> > boot through EFI. Finally, we add support in the build system and a
> > run script which is used to run an EFI app.
> >
> > After this set of patches one can build arm64 EFI tests:
> >
> > $> ./configure --enable-efi
> > $> make
> >
> > And use the run script to run an EFI tests:
> >
> > $> ./arm/efi/run ./arm/selftest.efi -smp 2 -m 256 -append "setup smp=2 mem=256"
> >
> > Or all tests:
> >
> > $> ./run_tests.sh
> >
> > There are a few items that this series does not address but they would
> > be useful to have:
> > - Support for booting the system from EL2. Currently, we assume that a
> > test starts EL1. This will be required to run EFI tests on sytems
> > that implement EL2.
> > - Support for reading environment variables and populating __envp.
> > - Support for discovering the PCI subsystem using ACPI.
> > - Get rid of other assumptions (e.g., vmalloc area) that don't hold on
> > real HW.
> > - Various fixes related to cache maintaince to better support turn the
> > MMU off.
> > - Switch to a new stack and avoid relying on the one provided by EFI.
> >
> > git branch: https://github.com/relokin/kvm-unit-tests/pull/new/target-efi-upstream-v5
> >
> > v4: https://lore.kernel.org/kvmarm/20230213101759.2577077-1-nikos.nikoleris@arm.com/
> > v3: https://lore.kernel.org/all/20220630100324.3153655-1-nikos.nikoleris@arm.com/
> > v2: https://lore.kernel.org/kvm/20220506205605.359830-1-nikos.nikoleris@arm.com/
> >
> > Changes in v5:
> > - Minor style changes (thanks Shaoqin).
> > - Avoid including lib/acpi.o to cflatobjs twice (thanks Drew).
> > - Increase NR_INITIAL_MEM_REGIONS to avoid overflows and add check when
> > we run out of space (thanks Shaoqin).
> >
> > Changes in v4:
> > - Removed patch that reworks cache maintenance when turning the MMU
> > off. This is not strictly required for EFI tests running with tcg and
> > will be addressed in a separate series by Alex.
> > - Fix compilation for arm (Alex).
> > - Convert ACPI tables to Linux style (Alex).
> >
> > Changes in v3:
> > - Addressed feedback from Drew, Alex and Ricardo. Many thanks for the reviews!
> > - Added support for discovering the GIC through ACPI
> > - Added a missing header file (<elf.h>)
> > - Added support for correctly parsing the outcome of tests (./run_tests)
> >
>
> Thanks, Nikos!
>
> I'd like to get an ack from either Paolo or Sean on the changes to ACPI,
> as they're shared with x86, and there are also some x86 code changes.
Actually, there are two build pipeline failures with the new ACPI code.
Please take a look at
https://gitlab.com/jones-drew/kvm-unit-tests/-/pipelines/852864569
Thanks,
drew
>
> Also,
>
> 1) It'd be nice if this worked with DT, too. We can use UEFI with DT
> when adding '-no-acpi' to the QEMU command line. setup_efi() needs
> to learn how to find the dtb and most the '#ifdef CONFIG_EFI's
> would need to change to a new CONFIG_ACPI guard.
>
> 2) The debug bp and ss tests fail with EFI, but not without, for me.
>
> 3) The timer test runs (and succeeds) when run with
> './arm/efi/run ./arm/timer.efi', but not when run with
> './run_tests.sh -g timer'. This is because UEFI takes
> up all the given timeout time (10s), and then the test times out.
> The hackyish fix below resolves it for me. I'll consider posting it
> as a real patch
>
> Thanks,
> drew
>
> diff --git a/scripts/arch-run.bash b/scripts/arch-run.bash
> index 51e4b97b27d1..72ce718b1170 100644
> --- a/scripts/arch-run.bash
> +++ b/scripts/arch-run.bash
> @@ -94,7 +94,17 @@ run_qemu_status ()
>
> timeout_cmd ()
> {
> + local s
> +
> if [ "$TIMEOUT" ] && [ "$TIMEOUT" != "0" ]; then
> + if [ "$CONFIG_EFI" = 'y' ]; then
> + s=${TIMEOUT: -1}
> + if [ "$s" = 's' ]; then
> + TIMEOUT=${TIMEOUT:0:-1}
> + ((TIMEOUT += 10)) # Add 10 seconds for booting UEFI
> + TIMEOUT="${TIMEOUT}s"
> + fi
> + fi
> echo "timeout -k 1s --foreground $TIMEOUT"
> fi
> }
^ permalink raw reply [flat|nested] 52+ messages in thread* Re: [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64
2023-04-29 16:21 ` Andrew Jones
@ 2023-04-30 0:02 ` Nikos Nikoleris
2023-05-01 11:21 ` Andrew Jones
0 siblings, 1 reply; 52+ messages in thread
From: Nikos Nikoleris @ 2023-04-30 0:02 UTC (permalink / raw)
To: Andrew Jones; +Cc: kvm, kvmarm, pbonzini, alexandru.elisei, ricarkol, seanjc
On 29/04/2023 17:21, Andrew Jones wrote:
> On Sat, Apr 29, 2023 at 06:18:25PM +0200, Andrew Jones wrote:
>> On Fri, Apr 28, 2023 at 01:03:36PM +0100, Nikos Nikoleris wrote:
>>> Hello,
>>>
>>> This series adds initial support for building arm64 tests as EFI
>>> apps and running them under QEMU. Much like x86_64, we import external
>>> dependencies from gnu-efi and adapt them to work with types and other
>>> assumptions from kvm-unit-tests. In addition, this series adds support
>>> for enumerating parts of the system using ACPI.
>>>
>>> The first set of patches, moves the existing ACPI code to the common
>>> lib path. Then, it extends definitions and functions to allow for more
>>> robust discovery of ACPI tables. We add support for setting up the PSCI
>>> conduit, discovering the UART, timers, GIC and cpus via ACPI. The code
>>> retains existing behavior and gives priority to discovery through DT
>>> when one has been provided.
>>>
>>> In the second set of patches, we add support for getting the command
>>> line from the EFI shell. This is a requirement for many of the
>>> existing arm64 tests.
>>>
>>> In the third set of patches, we import code from gnu-efi, make minor
>>> changes and add an alternative setup sequence from arm64 systems that
>>> boot through EFI. Finally, we add support in the build system and a
>>> run script which is used to run an EFI app.
>>>
>>> After this set of patches one can build arm64 EFI tests:
>>>
>>> $> ./configure --enable-efi
>>> $> make
>>>
>>> And use the run script to run an EFI tests:
>>>
>>> $> ./arm/efi/run ./arm/selftest.efi -smp 2 -m 256 -append "setup smp=2 mem=256"
>>>
>>> Or all tests:
>>>
>>> $> ./run_tests.sh
>>>
>>> There are a few items that this series does not address but they would
>>> be useful to have:
>>> - Support for booting the system from EL2. Currently, we assume that a
>>> test starts EL1. This will be required to run EFI tests on sytems
>>> that implement EL2.
>>> - Support for reading environment variables and populating __envp.
>>> - Support for discovering the PCI subsystem using ACPI.
>>> - Get rid of other assumptions (e.g., vmalloc area) that don't hold on
>>> real HW.
>>> - Various fixes related to cache maintaince to better support turn the
>>> MMU off.
>>> - Switch to a new stack and avoid relying on the one provided by EFI.
>>>
>>> git branch: https://github.com/relokin/kvm-unit-tests/pull/new/target-efi-upstream-v5
>>>
>>> v4: https://lore.kernel.org/kvmarm/20230213101759.2577077-1-nikos.nikoleris@arm.com/
>>> v3: https://lore.kernel.org/all/20220630100324.3153655-1-nikos.nikoleris@arm.com/
>>> v2: https://lore.kernel.org/kvm/20220506205605.359830-1-nikos.nikoleris@arm.com/
>>>
>>> Changes in v5:
>>> - Minor style changes (thanks Shaoqin).
>>> - Avoid including lib/acpi.o to cflatobjs twice (thanks Drew).
>>> - Increase NR_INITIAL_MEM_REGIONS to avoid overflows and add check when
>>> we run out of space (thanks Shaoqin).
>>>
>>> Changes in v4:
>>> - Removed patch that reworks cache maintenance when turning the MMU
>>> off. This is not strictly required for EFI tests running with tcg and
>>> will be addressed in a separate series by Alex.
>>> - Fix compilation for arm (Alex).
>>> - Convert ACPI tables to Linux style (Alex).
>>>
>>> Changes in v3:
>>> - Addressed feedback from Drew, Alex and Ricardo. Many thanks for the reviews!
>>> - Added support for discovering the GIC through ACPI
>>> - Added a missing header file (<elf.h>)
>>> - Added support for correctly parsing the outcome of tests (./run_tests)
>>>
>>
>> Thanks, Nikos!
>>
>> I'd like to get an ack from either Paolo or Sean on the changes to ACPI,
>> as they're shared with x86, and there are also some x86 code changes.
>
> Actually, there are two build pipeline failures with the new ACPI code.
> Please take a look at
>
> https://gitlab.com/jones-drew/kvm-unit-tests/-/pipelines/852864569
>
Thanks for reviewing the series!
I think this fixes the compilation issues:
diff --git a/lib/acpi.h b/lib/acpi.h
index 202d832e..c330c877 100644
--- a/lib/acpi.h
+++ b/lib/acpi.h
@@ -292,7 +292,8 @@ struct acpi_table_gtdt {
u32 platform_timer_offset;
};
-#pragma pack(0)
+/* Reset to default packing */
+#pragma pack()
void set_efi_rsdp(struct acpi_table_rsdp *rsdp);
void *find_acpi_table_addr(u32 sig);
diff --git a/lib/acpi.c b/lib/acpi.c
index 760cd8b2..0440cddb 100644
--- a/lib/acpi.c
+++ b/lib/acpi.c
@@ -70,7 +70,7 @@ void *find_acpi_table_addr(u32 sig)
return rsdt;
if (rsdp->revision >= 2) {
- xsdt = (void *)rsdp->xsdt_physical_address;
+ xsdt = (void *)(ulong) rsdp->xsdt_physical_address;
if (xsdt && xsdt->signature != XSDT_SIGNATURE)
xsdt = NULL;
}
> Thanks,
> drew
>
>>
>> Also,
>>
>> 1) It'd be nice if this worked with DT, too. We can use UEFI with DT
>> when adding '-no-acpi' to the QEMU command line. setup_efi() needs
>> to learn how to find the dtb and most the '#ifdef CONFIG_EFI's
>> would need to change to a new CONFIG_ACPI guard.
>>
I had a quick look at it at some point and it didn't look
straightforward but I'll check again.
>> 2) The debug bp and ss tests fail with EFI, but not without, for me.
>>
I think, I've found the problem, the patch below fixes it for me.
diff --git a/arm/debug.c b/arm/debug.c
index b3e9749c..126fa267 100644
--- a/arm/debug.c
+++ b/arm/debug.c
@@ -292,11 +292,14 @@ static noinline void test_hw_bp(bool migrate)
hw_bp_idx = 0;
/* Trap on up to 16 debug exception unmask instructions. */
- asm volatile("hw_bp0:\n"
- "msr daifclr, #8; msr daifclr, #8; msr daifclr, #8; msr
daifclr, #8\n"
- "msr daifclr, #8; msr daifclr, #8; msr daifclr, #8; msr
daifclr, #8\n"
- "msr daifclr, #8; msr daifclr, #8; msr daifclr, #8; msr
daifclr, #8\n"
- "msr daifclr, #8; msr daifclr, #8; msr daifclr, #8; msr
daifclr, #8\n");
+ asm volatile(
+ ".globl hw_bp0\n"
+ "hw_bp0:\n"
+ "msr daifclr, #8; msr daifclr, #8; msr daifclr,
#8; msr daifclr, #8\n"
+ "msr daifclr, #8; msr daifclr, #8; msr daifclr,
#8; msr daifclr, #8\n"
+ "msr daifclr, #8; msr daifclr, #8; msr daifclr,
#8; msr daifclr, #8\n"
+ "msr daifclr, #8; msr daifclr, #8; msr daifclr,
#8; msr daifclr, #8\n"
+ );
for (i = 0, addr = (uint64_t)&hw_bp0; i < num_bp; i++, addr += 4)
report(hw_bp_addr[i] == addr, "hw breakpoint: %d", i);
@@ -367,11 +370,14 @@ static noinline void test_ss(bool migrate)
asm volatile("msr daifclr, #8");
- asm volatile("ss_start:\n"
+ asm volatile(
+ ".globl ss_start\n"
+ "ss_start:\n"
"mrs x0, esr_el1\n"
"add x0, x0, #1\n"
"msr daifset, #8\n"
- : : : "x0");
+ : : : "x0"
+ );
report(ss_addr[0] == (uint64_t)&ss_start, "single step");
}
>> 3) The timer test runs (and succeeds) when run with
>> './arm/efi/run ./arm/timer.efi', but not when run with
>> './run_tests.sh -g timer'. This is because UEFI takes
>> up all the given timeout time (10s), and then the test times out.
>> The hackyish fix below resolves it for me. I'll consider posting it
>> as a real patch
>>
I see. I didn't hit the timeout on my test machine but I tried on a
slower machine and I did.
New branch with the fixups here:
https://github.com/relokin/kvm-unit-tests/pull/new/target-efi-upstream-v5
Many thanks,
Nikos
>> Thanks,
>> drew
>>
>> diff --git a/scripts/arch-run.bash b/scripts/arch-run.bash
>> index 51e4b97b27d1..72ce718b1170 100644
>> --- a/scripts/arch-run.bash
>> +++ b/scripts/arch-run.bash
>> @@ -94,7 +94,17 @@ run_qemu_status ()
>>
>> timeout_cmd ()
>> {
>> + local s
>> +
>> if [ "$TIMEOUT" ] && [ "$TIMEOUT" != "0" ]; then
>> + if [ "$CONFIG_EFI" = 'y' ]; then
>> + s=${TIMEOUT: -1}
>> + if [ "$s" = 's' ]; then
>> + TIMEOUT=${TIMEOUT:0:-1}
>> + ((TIMEOUT += 10)) # Add 10 seconds for booting UEFI
>> + TIMEOUT="${TIMEOUT}s"
>> + fi
>> + fi
>> echo "timeout -k 1s --foreground $TIMEOUT"
>> fi
>> }
^ permalink raw reply related [flat|nested] 52+ messages in thread* Re: [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64
2023-04-30 0:02 ` Nikos Nikoleris
@ 2023-05-01 11:21 ` Andrew Jones
2023-05-01 22:27 ` Nikos Nikoleris
0 siblings, 1 reply; 52+ messages in thread
From: Andrew Jones @ 2023-05-01 11:21 UTC (permalink / raw)
To: Nikos Nikoleris; +Cc: kvm, kvmarm, pbonzini, alexandru.elisei, ricarkol, seanjc
On Sun, Apr 30, 2023 at 01:02:42AM +0100, Nikos Nikoleris wrote:
> On 29/04/2023 17:21, Andrew Jones wrote:
> > On Sat, Apr 29, 2023 at 06:18:25PM +0200, Andrew Jones wrote:
> > > On Fri, Apr 28, 2023 at 01:03:36PM +0100, Nikos Nikoleris wrote:
> > > > Hello,
> > > >
> > > > This series adds initial support for building arm64 tests as EFI
> > > > apps and running them under QEMU. Much like x86_64, we import external
> > > > dependencies from gnu-efi and adapt them to work with types and other
> > > > assumptions from kvm-unit-tests. In addition, this series adds support
> > > > for enumerating parts of the system using ACPI.
> > > >
> > > > The first set of patches, moves the existing ACPI code to the common
> > > > lib path. Then, it extends definitions and functions to allow for more
> > > > robust discovery of ACPI tables. We add support for setting up the PSCI
> > > > conduit, discovering the UART, timers, GIC and cpus via ACPI. The code
> > > > retains existing behavior and gives priority to discovery through DT
> > > > when one has been provided.
> > > >
> > > > In the second set of patches, we add support for getting the command
> > > > line from the EFI shell. This is a requirement for many of the
> > > > existing arm64 tests.
> > > >
> > > > In the third set of patches, we import code from gnu-efi, make minor
> > > > changes and add an alternative setup sequence from arm64 systems that
> > > > boot through EFI. Finally, we add support in the build system and a
> > > > run script which is used to run an EFI app.
> > > >
> > > > After this set of patches one can build arm64 EFI tests:
> > > >
> > > > $> ./configure --enable-efi
> > > > $> make
> > > >
> > > > And use the run script to run an EFI tests:
> > > >
> > > > $> ./arm/efi/run ./arm/selftest.efi -smp 2 -m 256 -append "setup smp=2 mem=256"
> > > >
> > > > Or all tests:
> > > >
> > > > $> ./run_tests.sh
> > > >
> > > > There are a few items that this series does not address but they would
> > > > be useful to have:
> > > > - Support for booting the system from EL2. Currently, we assume that a
> > > > test starts EL1. This will be required to run EFI tests on sytems
> > > > that implement EL2.
> > > > - Support for reading environment variables and populating __envp.
> > > > - Support for discovering the PCI subsystem using ACPI.
> > > > - Get rid of other assumptions (e.g., vmalloc area) that don't hold on
> > > > real HW.
> > > > - Various fixes related to cache maintaince to better support turn the
> > > > MMU off.
> > > > - Switch to a new stack and avoid relying on the one provided by EFI.
> > > >
> > > > git branch: https://github.com/relokin/kvm-unit-tests/pull/new/target-efi-upstream-v5
> > > >
> > > > v4: https://lore.kernel.org/kvmarm/20230213101759.2577077-1-nikos.nikoleris@arm.com/
> > > > v3: https://lore.kernel.org/all/20220630100324.3153655-1-nikos.nikoleris@arm.com/
> > > > v2: https://lore.kernel.org/kvm/20220506205605.359830-1-nikos.nikoleris@arm.com/
> > > >
> > > > Changes in v5:
> > > > - Minor style changes (thanks Shaoqin).
> > > > - Avoid including lib/acpi.o to cflatobjs twice (thanks Drew).
> > > > - Increase NR_INITIAL_MEM_REGIONS to avoid overflows and add check when
> > > > we run out of space (thanks Shaoqin).
> > > >
> > > > Changes in v4:
> > > > - Removed patch that reworks cache maintenance when turning the MMU
> > > > off. This is not strictly required for EFI tests running with tcg and
> > > > will be addressed in a separate series by Alex.
> > > > - Fix compilation for arm (Alex).
> > > > - Convert ACPI tables to Linux style (Alex).
> > > >
> > > > Changes in v3:
> > > > - Addressed feedback from Drew, Alex and Ricardo. Many thanks for the reviews!
> > > > - Added support for discovering the GIC through ACPI
> > > > - Added a missing header file (<elf.h>)
> > > > - Added support for correctly parsing the outcome of tests (./run_tests)
> > > >
> > >
> > > Thanks, Nikos!
> > >
> > > I'd like to get an ack from either Paolo or Sean on the changes to ACPI,
> > > as they're shared with x86, and there are also some x86 code changes.
> >
> > Actually, there are two build pipeline failures with the new ACPI code.
> > Please take a look at
> >
> > https://gitlab.com/jones-drew/kvm-unit-tests/-/pipelines/852864569
> >
>
> Thanks for reviewing the series!
>
> I think this fixes the compilation issues:
>
> diff --git a/lib/acpi.h b/lib/acpi.h
> index 202d832e..c330c877 100644
> --- a/lib/acpi.h
> +++ b/lib/acpi.h
> @@ -292,7 +292,8 @@ struct acpi_table_gtdt {
> u32 platform_timer_offset;
> };
>
> -#pragma pack(0)
> +/* Reset to default packing */
> +#pragma pack()
>
> void set_efi_rsdp(struct acpi_table_rsdp *rsdp);
> void *find_acpi_table_addr(u32 sig);
> diff --git a/lib/acpi.c b/lib/acpi.c
> index 760cd8b2..0440cddb 100644
> --- a/lib/acpi.c
> +++ b/lib/acpi.c
> @@ -70,7 +70,7 @@ void *find_acpi_table_addr(u32 sig)
> return rsdt;
>
> if (rsdp->revision >= 2) {
> - xsdt = (void *)rsdp->xsdt_physical_address;
> + xsdt = (void *)(ulong) rsdp->xsdt_physical_address;
> if (xsdt && xsdt->signature != XSDT_SIGNATURE)
> xsdt = NULL;
> }
>
> > Thanks,
> > drew
> >
> > >
> > > Also,
> > >
> > > 1) It'd be nice if this worked with DT, too. We can use UEFI with DT
> > > when adding '-no-acpi' to the QEMU command line. setup_efi() needs
> > > to learn how to find the dtb and most the '#ifdef CONFIG_EFI's
> > > would need to change to a new CONFIG_ACPI guard.
> > >
>
> I had a quick look at it at some point and it didn't look straightforward
> but I'll check again.
>
> > > 2) The debug bp and ss tests fail with EFI, but not without, for me.
> > >
>
> I think, I've found the problem, the patch below fixes it for me.
>
> diff --git a/arm/debug.c b/arm/debug.c
> index b3e9749c..126fa267 100644
> --- a/arm/debug.c
> +++ b/arm/debug.c
> @@ -292,11 +292,14 @@ static noinline void test_hw_bp(bool migrate)
> hw_bp_idx = 0;
>
> /* Trap on up to 16 debug exception unmask instructions. */
> - asm volatile("hw_bp0:\n"
> - "msr daifclr, #8; msr daifclr, #8; msr daifclr, #8; msr
> daifclr, #8\n"
> - "msr daifclr, #8; msr daifclr, #8; msr daifclr, #8; msr
> daifclr, #8\n"
> - "msr daifclr, #8; msr daifclr, #8; msr daifclr, #8; msr
> daifclr, #8\n"
> - "msr daifclr, #8; msr daifclr, #8; msr daifclr, #8; msr
> daifclr, #8\n");
> + asm volatile(
> + ".globl hw_bp0\n"
> + "hw_bp0:\n"
> + "msr daifclr, #8; msr daifclr, #8; msr daifclr, #8;
> msr daifclr, #8\n"
> + "msr daifclr, #8; msr daifclr, #8; msr daifclr, #8;
> msr daifclr, #8\n"
> + "msr daifclr, #8; msr daifclr, #8; msr daifclr, #8;
> msr daifclr, #8\n"
> + "msr daifclr, #8; msr daifclr, #8; msr daifclr, #8;
> msr daifclr, #8\n"
> + );
>
> for (i = 0, addr = (uint64_t)&hw_bp0; i < num_bp; i++, addr += 4)
> report(hw_bp_addr[i] == addr, "hw breakpoint: %d", i);
> @@ -367,11 +370,14 @@ static noinline void test_ss(bool migrate)
>
> asm volatile("msr daifclr, #8");
>
> - asm volatile("ss_start:\n"
> + asm volatile(
> + ".globl ss_start\n"
> + "ss_start:\n"
> "mrs x0, esr_el1\n"
> "add x0, x0, #1\n"
> "msr daifset, #8\n"
> - : : : "x0");
> + : : : "x0"
> + );
>
> report(ss_addr[0] == (uint64_t)&ss_start, "single step");
> }
>
> > > 3) The timer test runs (and succeeds) when run with
> > > './arm/efi/run ./arm/timer.efi', but not when run with
> > > './run_tests.sh -g timer'. This is because UEFI takes
> > > up all the given timeout time (10s), and then the test times out.
> > > The hackyish fix below resolves it for me. I'll consider posting it
> > > as a real patch
> > >
>
> I see. I didn't hit the timeout on my test machine but I tried on a slower
> machine and I did.
>
> New branch with the fixups here:
>
> https://github.com/relokin/kvm-unit-tests/pull/new/target-efi-upstream-v5
Thanks for the quick fixes. Can you update your tree and make an MR? I
no longer use github.com/rhdrjones/kvm-unit-tests. I use
https://gitlab.com/jones-drew/kvm-unit-tests.git
Thanks,
drew
>
> Many thanks,
>
> Nikos
>
> > > Thanks,
> > > drew
> > >
> > > diff --git a/scripts/arch-run.bash b/scripts/arch-run.bash
> > > index 51e4b97b27d1..72ce718b1170 100644
> > > --- a/scripts/arch-run.bash
> > > +++ b/scripts/arch-run.bash
> > > @@ -94,7 +94,17 @@ run_qemu_status ()
> > > timeout_cmd ()
> > > {
> > > + local s
> > > +
> > > if [ "$TIMEOUT" ] && [ "$TIMEOUT" != "0" ]; then
> > > + if [ "$CONFIG_EFI" = 'y' ]; then
> > > + s=${TIMEOUT: -1}
> > > + if [ "$s" = 's' ]; then
> > > + TIMEOUT=${TIMEOUT:0:-1}
> > > + ((TIMEOUT += 10)) # Add 10 seconds for booting UEFI
> > > + TIMEOUT="${TIMEOUT}s"
> > > + fi
> > > + fi
> > > echo "timeout -k 1s --foreground $TIMEOUT"
> > > fi
> > > }
^ permalink raw reply [flat|nested] 52+ messages in thread* Re: [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64
2023-05-01 11:21 ` Andrew Jones
@ 2023-05-01 22:27 ` Nikos Nikoleris
2023-05-02 7:32 ` Andrew Jones
0 siblings, 1 reply; 52+ messages in thread
From: Nikos Nikoleris @ 2023-05-01 22:27 UTC (permalink / raw)
To: Andrew Jones; +Cc: kvm, kvmarm, pbonzini, alexandru.elisei, ricarkol, seanjc
On 01/05/2023 12:21, Andrew Jones wrote:
> On Sun, Apr 30, 2023 at 01:02:42AM +0100, Nikos Nikoleris wrote:
>> On 29/04/2023 17:21, Andrew Jones wrote:
>>> On Sat, Apr 29, 2023 at 06:18:25PM +0200, Andrew Jones wrote:
>>>> On Fri, Apr 28, 2023 at 01:03:36PM +0100, Nikos Nikoleris wrote:
>>>>> Hello,
>>>>>
>>>>> This series adds initial support for building arm64 tests as EFI
>>>>> apps and running them under QEMU. Much like x86_64, we import external
>>>>> dependencies from gnu-efi and adapt them to work with types and other
>>>>> assumptions from kvm-unit-tests. In addition, this series adds support
>>>>> for enumerating parts of the system using ACPI.
>>>>>
>>>>> The first set of patches, moves the existing ACPI code to the common
>>>>> lib path. Then, it extends definitions and functions to allow for more
>>>>> robust discovery of ACPI tables. We add support for setting up the PSCI
>>>>> conduit, discovering the UART, timers, GIC and cpus via ACPI. The code
>>>>> retains existing behavior and gives priority to discovery through DT
>>>>> when one has been provided.
>>>>>
>>>>> In the second set of patches, we add support for getting the command
>>>>> line from the EFI shell. This is a requirement for many of the
>>>>> existing arm64 tests.
>>>>>
>>>>> In the third set of patches, we import code from gnu-efi, make minor
>>>>> changes and add an alternative setup sequence from arm64 systems that
>>>>> boot through EFI. Finally, we add support in the build system and a
>>>>> run script which is used to run an EFI app.
>>>>>
>>>>> After this set of patches one can build arm64 EFI tests:
>>>>>
>>>>> $> ./configure --enable-efi
>>>>> $> make
>>>>>
>>>>> And use the run script to run an EFI tests:
>>>>>
>>>>> $> ./arm/efi/run ./arm/selftest.efi -smp 2 -m 256 -append "setup smp=2 mem=256"
>>>>>
>>>>> Or all tests:
>>>>>
>>>>> $> ./run_tests.sh
>>>>>
>>>>> There are a few items that this series does not address but they would
>>>>> be useful to have:
>>>>> - Support for booting the system from EL2. Currently, we assume that a
>>>>> test starts EL1. This will be required to run EFI tests on sytems
>>>>> that implement EL2.
>>>>> - Support for reading environment variables and populating __envp.
>>>>> - Support for discovering the PCI subsystem using ACPI.
>>>>> - Get rid of other assumptions (e.g., vmalloc area) that don't hold on
>>>>> real HW.
>>>>> - Various fixes related to cache maintaince to better support turn the
>>>>> MMU off.
>>>>> - Switch to a new stack and avoid relying on the one provided by EFI.
>>>>>
>>>>> git branch: https://github.com/relokin/kvm-unit-tests/pull/new/target-efi-upstream-v5
>>>>>
>>>>> v4: https://lore.kernel.org/kvmarm/20230213101759.2577077-1-nikos.nikoleris@arm.com/
>>>>> v3: https://lore.kernel.org/all/20220630100324.3153655-1-nikos.nikoleris@arm.com/
>>>>> v2: https://lore.kernel.org/kvm/20220506205605.359830-1-nikos.nikoleris@arm.com/
>>>>>
>>>>> Changes in v5:
>>>>> - Minor style changes (thanks Shaoqin).
>>>>> - Avoid including lib/acpi.o to cflatobjs twice (thanks Drew).
>>>>> - Increase NR_INITIAL_MEM_REGIONS to avoid overflows and add check when
>>>>> we run out of space (thanks Shaoqin).
>>>>>
>>>>> Changes in v4:
>>>>> - Removed patch that reworks cache maintenance when turning the MMU
>>>>> off. This is not strictly required for EFI tests running with tcg and
>>>>> will be addressed in a separate series by Alex.
>>>>> - Fix compilation for arm (Alex).
>>>>> - Convert ACPI tables to Linux style (Alex).
>>>>>
>>>>> Changes in v3:
>>>>> - Addressed feedback from Drew, Alex and Ricardo. Many thanks for the reviews!
>>>>> - Added support for discovering the GIC through ACPI
>>>>> - Added a missing header file (<elf.h>)
>>>>> - Added support for correctly parsing the outcome of tests (./run_tests)
>>>>>
>>>>
>>>> Thanks, Nikos!
>>>>
>>>> I'd like to get an ack from either Paolo or Sean on the changes to ACPI,
>>>> as they're shared with x86, and there are also some x86 code changes.
>>>
>>> Actually, there are two build pipeline failures with the new ACPI code.
>>> Please take a look at
>>>
>>> https://gitlab.com/jones-drew/kvm-unit-tests/-/pipelines/852864569
>>>
>>
>> Thanks for reviewing the series!
>>
>> I think this fixes the compilation issues:
>>
>> diff --git a/lib/acpi.h b/lib/acpi.h
>> index 202d832e..c330c877 100644
>> --- a/lib/acpi.h
>> +++ b/lib/acpi.h
>> @@ -292,7 +292,8 @@ struct acpi_table_gtdt {
>> u32 platform_timer_offset;
>> };
>>
>> -#pragma pack(0)
>> +/* Reset to default packing */
>> +#pragma pack()
>>
>> void set_efi_rsdp(struct acpi_table_rsdp *rsdp);
>> void *find_acpi_table_addr(u32 sig);
>> diff --git a/lib/acpi.c b/lib/acpi.c
>> index 760cd8b2..0440cddb 100644
>> --- a/lib/acpi.c
>> +++ b/lib/acpi.c
>> @@ -70,7 +70,7 @@ void *find_acpi_table_addr(u32 sig)
>> return rsdt;
>>
>> if (rsdp->revision >= 2) {
>> - xsdt = (void *)rsdp->xsdt_physical_address;
>> + xsdt = (void *)(ulong) rsdp->xsdt_physical_address;
>> if (xsdt && xsdt->signature != XSDT_SIGNATURE)
>> xsdt = NULL;
>> }
>>
>>> Thanks,
>>> drew
>>>
>>>>
>>>> Also,
>>>>
>>>> 1) It'd be nice if this worked with DT, too. We can use UEFI with DT
>>>> when adding '-no-acpi' to the QEMU command line. setup_efi() needs
>>>> to learn how to find the dtb and most the '#ifdef CONFIG_EFI's
>>>> would need to change to a new CONFIG_ACPI guard.
>>>>
>>
>> I had a quick look at it at some point and it didn't look straightforward
>> but I'll check again.
>>
>>>> 2) The debug bp and ss tests fail with EFI, but not without, for me.
>>>>
>>
>> I think, I've found the problem, the patch below fixes it for me.
>>
>> diff --git a/arm/debug.c b/arm/debug.c
>> index b3e9749c..126fa267 100644
>> --- a/arm/debug.c
>> +++ b/arm/debug.c
>> @@ -292,11 +292,14 @@ static noinline void test_hw_bp(bool migrate)
>> hw_bp_idx = 0;
>>
>> /* Trap on up to 16 debug exception unmask instructions. */
>> - asm volatile("hw_bp0:\n"
>> - "msr daifclr, #8; msr daifclr, #8; msr daifclr, #8; msr
>> daifclr, #8\n"
>> - "msr daifclr, #8; msr daifclr, #8; msr daifclr, #8; msr
>> daifclr, #8\n"
>> - "msr daifclr, #8; msr daifclr, #8; msr daifclr, #8; msr
>> daifclr, #8\n"
>> - "msr daifclr, #8; msr daifclr, #8; msr daifclr, #8; msr
>> daifclr, #8\n");
>> + asm volatile(
>> + ".globl hw_bp0\n"
>> + "hw_bp0:\n"
>> + "msr daifclr, #8; msr daifclr, #8; msr daifclr, #8;
>> msr daifclr, #8\n"
>> + "msr daifclr, #8; msr daifclr, #8; msr daifclr, #8;
>> msr daifclr, #8\n"
>> + "msr daifclr, #8; msr daifclr, #8; msr daifclr, #8;
>> msr daifclr, #8\n"
>> + "msr daifclr, #8; msr daifclr, #8; msr daifclr, #8;
>> msr daifclr, #8\n"
>> + );
>>
>> for (i = 0, addr = (uint64_t)&hw_bp0; i < num_bp; i++, addr += 4)
>> report(hw_bp_addr[i] == addr, "hw breakpoint: %d", i);
>> @@ -367,11 +370,14 @@ static noinline void test_ss(bool migrate)
>>
>> asm volatile("msr daifclr, #8");
>>
>> - asm volatile("ss_start:\n"
>> + asm volatile(
>> + ".globl ss_start\n"
>> + "ss_start:\n"
>> "mrs x0, esr_el1\n"
>> "add x0, x0, #1\n"
>> "msr daifset, #8\n"
>> - : : : "x0");
>> + : : : "x0"
>> + );
>>
>> report(ss_addr[0] == (uint64_t)&ss_start, "single step");
>> }
>>
>>>> 3) The timer test runs (and succeeds) when run with
>>>> './arm/efi/run ./arm/timer.efi', but not when run with
>>>> './run_tests.sh -g timer'. This is because UEFI takes
>>>> up all the given timeout time (10s), and then the test times out.
>>>> The hackyish fix below resolves it for me. I'll consider posting it
>>>> as a real patch
>>>>
>>
>> I see. I didn't hit the timeout on my test machine but I tried on a slower
>> machine and I did.
>>
>> New branch with the fixups here:
>>
>> https://github.com/relokin/kvm-unit-tests/pull/new/target-efi-upstream-v5
>
> Thanks for the quick fixes. Can you update your tree and make an MR? I
> no longer use github.com/rhdrjones/kvm-unit-tests. I use
>
> https://gitlab.com/jones-drew/kvm-unit-tests.git
>
You mean a MR into your repo and to the branch arm/queue, don't you?
I've tried doing that but I get an error: "Target branch "arm/queue"
does not exist", but it allows me to create a MR into other repos. Am I
doing something wrong?
My branch on gitlab:
https://gitlab.com/nnikoleris/kvm-unit-tests/-/tree/target-efi-upstream-v6-pre
Has the new fixups squashed and I've added Shaoqin's Reviewed-by tags.
And the branch with the fixups separately lives here:
https://gitlab.com/nnikoleris/kvm-unit-tests/-/tree/target-efi-upstream-v5-fixups
Do you want me to add your patch as well? Or are you going to add it
afterwards? Meanwhile, I've tried adding support for booting using a
fdt. I think it's not too hard, but I wouldn't mind merging this series
first and looking at the patches for the fdt support later.
Thanks,
Nikos
> Thanks,
> drew
>
>>
>> Many thanks,
>>
>> Nikos
>>
>>>> Thanks,
>>>> drew
>>>>
>>>> diff --git a/scripts/arch-run.bash b/scripts/arch-run.bash
>>>> index 51e4b97b27d1..72ce718b1170 100644
>>>> --- a/scripts/arch-run.bash
>>>> +++ b/scripts/arch-run.bash
>>>> @@ -94,7 +94,17 @@ run_qemu_status ()
>>>> timeout_cmd ()
>>>> {
>>>> + local s
>>>> +
>>>> if [ "$TIMEOUT" ] && [ "$TIMEOUT" != "0" ]; then
>>>> + if [ "$CONFIG_EFI" = 'y' ]; then
>>>> + s=${TIMEOUT: -1}
>>>> + if [ "$s" = 's' ]; then
>>>> + TIMEOUT=${TIMEOUT:0:-1}
>>>> + ((TIMEOUT += 10)) # Add 10 seconds for booting UEFI
>>>> + TIMEOUT="${TIMEOUT}s"
>>>> + fi
>>>> + fi
>>>> echo "timeout -k 1s --foreground $TIMEOUT"
>>>> fi
>>>> }
^ permalink raw reply [flat|nested] 52+ messages in thread* Re: [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64
2023-05-01 22:27 ` Nikos Nikoleris
@ 2023-05-02 7:32 ` Andrew Jones
2023-05-05 14:55 ` Nikos Nikoleris
0 siblings, 1 reply; 52+ messages in thread
From: Andrew Jones @ 2023-05-02 7:32 UTC (permalink / raw)
To: Nikos Nikoleris
Cc: kvm, kvmarm, pbonzini, alexandru.elisei, ricarkol, seanjc,
Shaoqin Huang
On Mon, May 01, 2023 at 11:27:23PM +0100, Nikos Nikoleris wrote:
> On 01/05/2023 12:21, Andrew Jones wrote:
...
> > > https://github.com/relokin/kvm-unit-tests/pull/new/target-efi-upstream-v5
> >
> > Thanks for the quick fixes. Can you update your tree and make an MR? I
> > no longer use github.com/rhdrjones/kvm-unit-tests. I use
> >
> > https://gitlab.com/jones-drew/kvm-unit-tests.git
> >
>
> You mean a MR into your repo and to the branch arm/queue, don't you? I've
> tried doing that but I get an error: "Target branch "arm/queue" does not
> exist", but it allows me to create a MR into other repos. Am I doing
> something wrong?
I'm not sure what's happening unless it's looking for the arm/queue branch
on the main gitlab kvm-unit-tests repo instead of mine.
>
> My branch on gitlab:
>
> https://gitlab.com/nnikoleris/kvm-unit-tests/-/tree/target-efi-upstream-v6-pre
Thanks. I grabbed the patches and applied to arm/queue,
https://gitlab.com/jones-drew/kvm-unit-tests/-/commits/arm/queue
> Do you want me to add your patch as well? Or are you going to add it
> afterwards?
We can do the additional runtime stuff on top. I have a couple other
script changes too and I think Shaoqin is looking at how to better cope
with migration tests.
> Meanwhile, I've tried adding support for booting using a fdt. I
> think it's not too hard, but I wouldn't mind merging this series first and
> looking at the patches for the fdt support later.
I'm also anxious to get this merged, but I'm a little reluctant to
take it without DT, since we may find other issues once we boot the
tests with DT. I also know how it's easy, at least for me, to let
stuff get dropped when their priorities reduce. If you have time now,
how about we poke at it until the end of the week? With some luck,
it'll be sorted out and we'll also have the x86 ack, which I'd like
to get, by then.
Thanks,
drew
^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64
2023-05-02 7:32 ` Andrew Jones
@ 2023-05-05 14:55 ` Nikos Nikoleris
0 siblings, 0 replies; 52+ messages in thread
From: Nikos Nikoleris @ 2023-05-05 14:55 UTC (permalink / raw)
To: Andrew Jones
Cc: kvm, kvmarm, pbonzini, alexandru.elisei, ricarkol, seanjc,
Shaoqin Huang
On 02/05/2023 08:32, Andrew Jones wrote:
> On Mon, May 01, 2023 at 11:27:23PM +0100, Nikos Nikoleris wrote:
>> On 01/05/2023 12:21, Andrew Jones wrote:
...
>
> I'm also anxious to get this merged, but I'm a little reluctant to
> take it without DT, since we may find other issues once we boot the
> tests with DT. I also know how it's easy, at least for me, to let
> stuff get dropped when their priorities reduce. If you have time now,
> how about we poke at it until the end of the week? With some luck,
> it'll be sorted out and we'll also have the x86 ack, which I'd like
> to get, by then.
>
Thanks Drew!
I've now implemented support for using an fdt when running tests as EFI
apps. You can find the two additional commits here:
https://gitlab.com/nnikoleris/kvm-unit-tests/-/tree/target-efi-upstream-v6-pre
But I suppose, at some point, I should also send the new version of this
series to the mailing list? What do you think?
Thanks,
Nikos
^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64
2023-04-28 12:03 [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Nikos Nikoleris
` (29 preceding siblings ...)
2023-04-29 16:18 ` [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64 Andrew Jones
@ 2023-05-01 12:09 ` Shaoqin Huang
2023-05-03 21:18 ` Nikos Nikoleris
30 siblings, 1 reply; 52+ messages in thread
From: Shaoqin Huang @ 2023-05-01 12:09 UTC (permalink / raw)
To: Nikos Nikoleris, kvm, kvmarm, andrew.jones
Cc: pbonzini, alexandru.elisei, ricarkol
Hi Nikos,
When I test this series by simply run ./run_tests.sh, some migration
test will hang up forever, like the `its-migration` test.
After have a quick look, when do the migration test, the guest can't be
migrated due to:
{"return": {"blocked-reasons": ["The qcow format used by node
'#block389' does not support live migration", "The vvfat (rw) format
used by node '#block085' does not support live migration"]}}
Although the guest will be timeout, but the script itself will not be
timeout. The infinite loop happened at here:
// script/arch-run.bash
151 # Wait for the migration to complete
152 migstatus=`qmp ${qmp1} '"query-migrate"' | grep return`
153 while ! grep -q '"completed"' <<<"$migstatus" ; do
154 sleep 1
155 migstatus=`qmp ${qmp1} '"query-migrate"' | grep
return`
156 if grep -q '"failed"' <<<"$migstatus" ; then
157 echo "ERROR: Migration failed." >&2
158 qmp ${qmp1} '"quit"'> ${qmpout1} 2>/dev/null
159 qmp ${qmp2} '"quit"'> ${qmpout2} 2>/dev/null
160 return 2
161 fi
162 done
Since the "query-migrate" here will never get "completed" or "failed",
so it will never exit.
Have you ever meet this problem?
Thanks,
Shaoqin
On 4/28/23 20:03, Nikos Nikoleris wrote:
> Hello,
>
> This series adds initial support for building arm64 tests as EFI
> apps and running them under QEMU. Much like x86_64, we import external
> dependencies from gnu-efi and adapt them to work with types and other
> assumptions from kvm-unit-tests. In addition, this series adds support
> for enumerating parts of the system using ACPI.
>
> The first set of patches, moves the existing ACPI code to the common
> lib path. Then, it extends definitions and functions to allow for more
> robust discovery of ACPI tables. We add support for setting up the PSCI
> conduit, discovering the UART, timers, GIC and cpus via ACPI. The code
> retains existing behavior and gives priority to discovery through DT
> when one has been provided.
>
> In the second set of patches, we add support for getting the command
> line from the EFI shell. This is a requirement for many of the
> existing arm64 tests.
>
> In the third set of patches, we import code from gnu-efi, make minor
> changes and add an alternative setup sequence from arm64 systems that
> boot through EFI. Finally, we add support in the build system and a
> run script which is used to run an EFI app.
>
> After this set of patches one can build arm64 EFI tests:
>
> $> ./configure --enable-efi
> $> make
>
> And use the run script to run an EFI tests:
>
> $> ./arm/efi/run ./arm/selftest.efi -smp 2 -m 256 -append "setup smp=2 mem=256"
>
> Or all tests:
>
> $> ./run_tests.sh
>
> There are a few items that this series does not address but they would
> be useful to have:
> - Support for booting the system from EL2. Currently, we assume that a
> test starts EL1. This will be required to run EFI tests on sytems
> that implement EL2.
> - Support for reading environment variables and populating __envp.
> - Support for discovering the PCI subsystem using ACPI.
> - Get rid of other assumptions (e.g., vmalloc area) that don't hold on
> real HW.
> - Various fixes related to cache maintaince to better support turn the
> MMU off.
> - Switch to a new stack and avoid relying on the one provided by EFI.
>
> git branch: https://github.com/relokin/kvm-unit-tests/pull/new/target-efi-upstream-v5
>
> v4: https://lore.kernel.org/kvmarm/20230213101759.2577077-1-nikos.nikoleris@arm.com/
> v3: https://lore.kernel.org/all/20220630100324.3153655-1-nikos.nikoleris@arm.com/
> v2: https://lore.kernel.org/kvm/20220506205605.359830-1-nikos.nikoleris@arm.com/
>
> Changes in v5:
> - Minor style changes (thanks Shaoqin).
> - Avoid including lib/acpi.o to cflatobjs twice (thanks Drew).
> - Increase NR_INITIAL_MEM_REGIONS to avoid overflows and add check when
> we run out of space (thanks Shaoqin).
>
> Changes in v4:
> - Removed patch that reworks cache maintenance when turning the MMU
> off. This is not strictly required for EFI tests running with tcg and
> will be addressed in a separate series by Alex.
> - Fix compilation for arm (Alex).
> - Convert ACPI tables to Linux style (Alex).
>
> Changes in v3:
> - Addressed feedback from Drew, Alex and Ricardo. Many thanks for the reviews!
> - Added support for discovering the GIC through ACPI
> - Added a missing header file (<elf.h>)
> - Added support for correctly parsing the outcome of tests (./run_tests)
>
> Thanks,
>
> Nikos
>
> Alexandru Elisei (2):
> lib/acpi: Convert table names to Linux style
> lib: arm: Print test exit status
>
> Andrew Jones (2):
> arm/arm64: Rename etext to _etext
> arm64: Add a new type of memory type flag MR_F_RESERVED
>
> Nikos Nikoleris (25):
> lib: Move acpi header and implementation to lib
> x86: Move x86_64-specific EFI CFLAGS to x86_64 Makefile
> lib: Apply Lindent to acpi.{c,h}
> lib: Fix style for acpi.{c,h}
> x86: Avoid references to fields of ACPI tables
> lib/acpi: Ensure all struct definition for ACPI tables are packed
> lib/acpi: Add support for the XSDT table
> lib/acpi: Extend the definition of the FADT table
> devicetree: Check that fdt is not NULL in dt_available()
> arm64: Add support for setting up the PSCI conduit through ACPI
> arm64: Add support for discovering the UART through ACPI
> arm64: Add support for timer initialization through ACPI
> arm64: Add support for cpu initialization through ACPI
> arm64: Add support for gic initialization through ACPI
> lib/printf: Support for precision modifier in printf
> lib/printf: Add support for printing wide strings
> lib/efi: Add support for getting the cmdline
> lib: Avoid ms_abi for calls related to EFI on arm64
> arm64: Add a setup sequence for systems that boot through EFI
> arm64: Copy code from GNU-EFI
> arm64: Change GNU-EFI imported code to use defined types
> arm64: Use code from the gnu-efi when booting with EFI
> lib: Avoid external dependency in libelf
> arm64: Add support for efi in Makefile
> arm64: Add an efi/run script
>
> scripts/runtime.bash | 13 +-
> arm/efi/run | 61 ++++++++
> arm/run | 14 +-
> configure | 17 +-
> Makefile | 4 -
> arm/Makefile.arm | 6 +
> arm/Makefile.arm64 | 22 ++-
> arm/Makefile.common | 47 ++++--
> x86/Makefile.common | 2 +-
> x86/Makefile.x86_64 | 4 +
> lib/linux/efi.h | 25 +++
> lib/arm/asm/setup.h | 9 ++
> lib/arm/asm/timer.h | 2 +
> lib/x86/asm/setup.h | 2 +-
> lib/acpi.h | 301 ++++++++++++++++++++++++++++++++++++
> lib/argv.h | 1 +
> lib/elf.h | 57 +++++++
> lib/libcflat.h | 1 +
> lib/x86/acpi.h | 112 --------------
> lib/acpi.c | 129 ++++++++++++++++
> lib/argv.c | 2 +-
> lib/arm/gic.c | 139 ++++++++++++++++-
> lib/arm/io.c | 41 ++++-
> lib/arm/mmu.c | 4 +
> lib/arm/psci.c | 37 ++++-
> lib/arm/setup.c | 269 ++++++++++++++++++++++++++------
> lib/arm/timer.c | 92 +++++++++++
> lib/devicetree.c | 2 +-
> lib/efi.c | 102 ++++++++++++
> lib/printf.c | 194 +++++++++++++++++++++--
> lib/x86/acpi.c | 82 ----------
> lib/x86/setup.c | 2 +-
> arm/efi/elf_aarch64_efi.lds | 63 ++++++++
> arm/flat.lds | 2 +-
> arm/cstart.S | 1 +
> arm/cstart64.S | 7 +
> arm/efi/crt0-efi-aarch64.S | 141 +++++++++++++++++
> arm/dummy.c | 12 ++
> arm/efi/reloc_aarch64.c | 94 +++++++++++
> arm/micro-bench.c | 4 +-
> arm/timer.c | 10 +-
> x86/s3.c | 21 +--
> x86/vmexit.c | 4 +-
> 43 files changed, 1831 insertions(+), 323 deletions(-)
> create mode 100755 arm/efi/run
> create mode 100644 lib/acpi.h
> create mode 100644 lib/elf.h
> delete mode 100644 lib/x86/acpi.h
> create mode 100644 lib/acpi.c
> create mode 100644 lib/arm/timer.c
> delete mode 100644 lib/x86/acpi.c
> create mode 100644 arm/efi/elf_aarch64_efi.lds
> create mode 100644 arm/efi/crt0-efi-aarch64.S
> create mode 100644 arm/dummy.c
> create mode 100644 arm/efi/reloc_aarch64.c
>
--
Shaoqin
^ permalink raw reply [flat|nested] 52+ messages in thread* Re: [kvm-unit-tests PATCH v5 00/29] EFI and ACPI support for arm64
2023-05-01 12:09 ` Shaoqin Huang
@ 2023-05-03 21:18 ` Nikos Nikoleris
0 siblings, 0 replies; 52+ messages in thread
From: Nikos Nikoleris @ 2023-05-03 21:18 UTC (permalink / raw)
To: Shaoqin Huang, kvm, kvmarm, andrew.jones
Cc: pbonzini, alexandru.elisei, ricarkol
Hi Shaoqin,
On 01/05/2023 13:09, Shaoqin Huang wrote:
> Hi Nikos,
>
> When I test this series by simply run ./run_tests.sh, some migration
> test will hang up forever, like the `its-migration` test.
>
> After have a quick look, when do the migration test, the guest can't be
> migrated due to:
>
> {"return": {"blocked-reasons": ["The qcow format used by node
> '#block389' does not support live migration", "The vvfat (rw) format
> used by node '#block085' does not support live migration"]}}
>
> Although the guest will be timeout, but the script itself will not be
> timeout. The infinite loop happened at here:
>
> // script/arch-run.bash
> 151 # Wait for the migration to complete
> 152 migstatus=`qmp ${qmp1} '"query-migrate"' | grep return`
> 153 while ! grep -q '"completed"' <<<"$migstatus" ; do
> 154 sleep 1
> 155 migstatus=`qmp ${qmp1} '"query-migrate"' | grep
> return`
> 156 if grep -q '"failed"' <<<"$migstatus" ; then
> 157 echo "ERROR: Migration failed." >&2
> 158 qmp ${qmp1} '"quit"'> ${qmpout1} 2>/dev/null
> 159 qmp ${qmp2} '"quit"'> ${qmpout2} 2>/dev/null
> 160 return 2
> 161 fi
> 162 done
>
> Since the "query-migrate" here will never get "completed" or "failed",
> so it will never exit.
> > Have you ever meet this problem?
I haven't encountered any problems on Linux but I think I am running
into something like this when I run on a MacOS. Unfortunately, I don't
know much about the migration tests and I don't know how they are
supposed to work in this case. Maybe the problem is that when we can
run_tests.sh for each test we first run dummy.efi?
Thanks,
Nikos
>
> Thanks,
> Shaoqin
>
> On 4/28/23 20:03, Nikos Nikoleris wrote:
>> Hello,
>>
>> This series adds initial support for building arm64 tests as EFI
>> apps and running them under QEMU. Much like x86_64, we import external
>> dependencies from gnu-efi and adapt them to work with types and other
>> assumptions from kvm-unit-tests. In addition, this series adds support
>> for enumerating parts of the system using ACPI.
>>
>> The first set of patches, moves the existing ACPI code to the common
>> lib path. Then, it extends definitions and functions to allow for more
>> robust discovery of ACPI tables. We add support for setting up the PSCI
>> conduit, discovering the UART, timers, GIC and cpus via ACPI. The code
>> retains existing behavior and gives priority to discovery through DT
>> when one has been provided.
>>
>> In the second set of patches, we add support for getting the command
>> line from the EFI shell. This is a requirement for many of the
>> existing arm64 tests.
>>
>> In the third set of patches, we import code from gnu-efi, make minor
>> changes and add an alternative setup sequence from arm64 systems that
>> boot through EFI. Finally, we add support in the build system and a
>> run script which is used to run an EFI app.
>>
>> After this set of patches one can build arm64 EFI tests:
>>
>> $> ./configure --enable-efi
>> $> make
>>
>> And use the run script to run an EFI tests:
>>
>> $> ./arm/efi/run ./arm/selftest.efi -smp 2 -m 256 -append "setup smp=2 mem=256"
>>
>> Or all tests:
>>
>> $> ./run_tests.sh
>>
>> There are a few items that this series does not address but they would
>> be useful to have:
>> - Support for booting the system from EL2. Currently, we assume that a
>> test starts EL1. This will be required to run EFI tests on sytems
>> that implement EL2.
>> - Support for reading environment variables and populating __envp.
>> - Support for discovering the PCI subsystem using ACPI.
>> - Get rid of other assumptions (e.g., vmalloc area) that don't hold on
>> real HW.
>> - Various fixes related to cache maintaince to better support turn the
>> MMU off.
>> - Switch to a new stack and avoid relying on the one provided by EFI.
>>
>> git branch: https://github.com/relokin/kvm-unit-tests/pull/new/target-efi-upstream-v5
>>
>> v4: https://lore.kernel.org/kvmarm/20230213101759.2577077-1-nikos.nikoleris@arm.com/
>> v3: https://lore.kernel.org/all/20220630100324.3153655-1-nikos.nikoleris@arm.com/
>> v2: https://lore.kernel.org/kvm/20220506205605.359830-1-nikos.nikoleris@arm.com/
>>
>> Changes in v5:
>> - Minor style changes (thanks Shaoqin).
>> - Avoid including lib/acpi.o to cflatobjs twice (thanks Drew).
>> - Increase NR_INITIAL_MEM_REGIONS to avoid overflows and add check when
>> we run out of space (thanks Shaoqin).
>>
>> Changes in v4:
>> - Removed patch that reworks cache maintenance when turning the MMU
>> off. This is not strictly required for EFI tests running with tcg and
>> will be addressed in a separate series by Alex.
>> - Fix compilation for arm (Alex).
>> - Convert ACPI tables to Linux style (Alex).
>>
>> Changes in v3:
>> - Addressed feedback from Drew, Alex and Ricardo. Many thanks for the reviews!
>> - Added support for discovering the GIC through ACPI
>> - Added a missing header file (<elf.h>)
>> - Added support for correctly parsing the outcome of tests (./run_tests)
>>
>> Thanks,
>>
>> Nikos
>>
>> Alexandru Elisei (2):
>> lib/acpi: Convert table names to Linux style
>> lib: arm: Print test exit status
>>
>> Andrew Jones (2):
>> arm/arm64: Rename etext to _etext
>> arm64: Add a new type of memory type flag MR_F_RESERVED
>>
>> Nikos Nikoleris (25):
>> lib: Move acpi header and implementation to lib
>> x86: Move x86_64-specific EFI CFLAGS to x86_64 Makefile
>> lib: Apply Lindent to acpi.{c,h}
>> lib: Fix style for acpi.{c,h}
>> x86: Avoid references to fields of ACPI tables
>> lib/acpi: Ensure all struct definition for ACPI tables are packed
>> lib/acpi: Add support for the XSDT table
>> lib/acpi: Extend the definition of the FADT table
>> devicetree: Check that fdt is not NULL in dt_available()
>> arm64: Add support for setting up the PSCI conduit through ACPI
>> arm64: Add support for discovering the UART through ACPI
>> arm64: Add support for timer initialization through ACPI
>> arm64: Add support for cpu initialization through ACPI
>> arm64: Add support for gic initialization through ACPI
>> lib/printf: Support for precision modifier in printf
>> lib/printf: Add support for printing wide strings
>> lib/efi: Add support for getting the cmdline
>> lib: Avoid ms_abi for calls related to EFI on arm64
>> arm64: Add a setup sequence for systems that boot through EFI
>> arm64: Copy code from GNU-EFI
>> arm64: Change GNU-EFI imported code to use defined types
>> arm64: Use code from the gnu-efi when booting with EFI
>> lib: Avoid external dependency in libelf
>> arm64: Add support for efi in Makefile
>> arm64: Add an efi/run script
>>
>> scripts/runtime.bash | 13 +-
>> arm/efi/run | 61 ++++++++
>> arm/run | 14 +-
>> configure | 17 +-
>> Makefile | 4 -
>> arm/Makefile.arm | 6 +
>> arm/Makefile.arm64 | 22 ++-
>> arm/Makefile.common | 47 ++++--
>> x86/Makefile.common | 2 +-
>> x86/Makefile.x86_64 | 4 +
>> lib/linux/efi.h | 25 +++
>> lib/arm/asm/setup.h | 9 ++
>> lib/arm/asm/timer.h | 2 +
>> lib/x86/asm/setup.h | 2 +-
>> lib/acpi.h | 301 ++++++++++++++++++++++++++++++++++++
>> lib/argv.h | 1 +
>> lib/elf.h | 57 +++++++
>> lib/libcflat.h | 1 +
>> lib/x86/acpi.h | 112 --------------
>> lib/acpi.c | 129 ++++++++++++++++
>> lib/argv.c | 2 +-
>> lib/arm/gic.c | 139 ++++++++++++++++-
>> lib/arm/io.c | 41 ++++-
>> lib/arm/mmu.c | 4 +
>> lib/arm/psci.c | 37 ++++-
>> lib/arm/setup.c | 269 ++++++++++++++++++++++++++------
>> lib/arm/timer.c | 92 +++++++++++
>> lib/devicetree.c | 2 +-
>> lib/efi.c | 102 ++++++++++++
>> lib/printf.c | 194 +++++++++++++++++++++--
>> lib/x86/acpi.c | 82 ----------
>> lib/x86/setup.c | 2 +-
>> arm/efi/elf_aarch64_efi.lds | 63 ++++++++
>> arm/flat.lds | 2 +-
>> arm/cstart.S | 1 +
>> arm/cstart64.S | 7 +
>> arm/efi/crt0-efi-aarch64.S | 141 +++++++++++++++++
>> arm/dummy.c | 12 ++
>> arm/efi/reloc_aarch64.c | 94 +++++++++++
>> arm/micro-bench.c | 4 +-
>> arm/timer.c | 10 +-
>> x86/s3.c | 21 +--
>> x86/vmexit.c | 4 +-
>> 43 files changed, 1831 insertions(+), 323 deletions(-)
>> create mode 100755 arm/efi/run
>> create mode 100644 lib/acpi.h
>> create mode 100644 lib/elf.h
>> delete mode 100644 lib/x86/acpi.h
>> create mode 100644 lib/acpi.c
>> create mode 100644 lib/arm/timer.c
>> delete mode 100644 lib/x86/acpi.c
>> create mode 100644 arm/efi/elf_aarch64_efi.lds
>> create mode 100644 arm/efi/crt0-efi-aarch64.S
>> create mode 100644 arm/dummy.c
>> create mode 100644 arm/efi/reloc_aarch64.c
>>
>
^ permalink raw reply [flat|nested] 52+ messages in thread