diff --git a/MAINTAINERS b/MAINTAINERS
index ef2cbb3..e338b62 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -487,6 +487,9 @@ M:	shuyiqi <shuyiqi@phytium.com.cn>
 S:	Maintained
 F:	drivers/pci/pcie_phytium.c
 F:	arch/arm/dts/phytium-durian.dts
+F:	arch/arm/include/asm/acpi_table.h
+F:	arch/arm/include/asm/acpi_table/*
+F:	arch/arm/lib/acpi_table.c
 
 BINMAN
 M:	Simon Glass <sjg@chromium.org>
diff --git a/Makefile b/Makefile
index 7485bc2..53ddae3 100644
--- a/Makefile
+++ b/Makefile
@@ -1953,6 +1953,7 @@ clean: $(clean-dirs)
 		-o -name '*.symtypes' -o -name 'modules.order' \
 		-o -name modules.builtin -o -name '.tmp_*.o.*' \
 		-o -name 'dsdt.aml' -o -name 'dsdt.asl.tmp' -o -name 'dsdt.c' \
+		-o -name 'ssdt.aml' -o -name 'ssdt.asl.tmp' -o -name 'ssdt.c' \
 		-o -name '*.efi' -o -name '*.gcno' -o -name '*.so' \) \
 		-type f -print | xargs rm -f \
 		bl31.c bl31.elf bl31_*.bin image.map tispl.bin*
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f96841c..0cd187b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -354,6 +354,75 @@ config ARM_SMCCC
 	  This should be enabled if U-Boot needs to communicate with system
 	  firmware (for example, PSCI) according to SMCCC.
 
+menuconfig ARM_ACPI_TABLE
+    bool "Support ACPI (Advanced Configuration and Power Interface) for ARM"
+    depends on ARM
+    help
+      The Advanced Configuration and Power Interface (ACPI) specification
+      provides an open standard for device configuration and management
+      by the operating system. It defines platform-independent interfaces
+      for configuration and power management monitoring.
+
+if ARM_ACPI_TABLE
+
+config DSDT_TABLE
+    bool "support DSDT (DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE) TABLE"
+    depends on ARM
+    help
+      DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE (DSDT)
+      Say Y here if you want to support dsdt table.
+
+config SSDT_TABLE
+    bool "support SSDT (SECONDARY_SYSTEM_DESCRIPTION_TABLE) TABLE"
+    depends on ARM
+    help
+      SECONDARY_SYSTEM_DESCRIPTION_TABLE (SSDT)
+      Say Y here if you want to support ssdt table.
+
+config FADT_TABLE
+    bool "support FADT (FIXED_ACPI_DESCRIPTION_TABLE) TABLE"
+    depends on ARM
+    help
+      FIXED_ACPI_DESCRIPTION_TABLE (FADT)
+      Say Y here if you want to support fadt table.
+
+config GTDT_TABLE
+    bool "support GTDT (GENERIC_TIMER_DESCRIPTION_TABLE) TABLE"
+    depends on ARM
+    help
+      GENERIC_TIMER_DESCRIPTION_TABLE (GTDT)
+      Say Y here if you want to support gtdt table.
+
+config MADT_TABLE
+    bool "support MADT (MULTIPLE_APIC_DESCRIPTION_TABLE) TABLE"
+    depends on ARM
+    help
+      MULTIPLE_APIC_DESCRIPTION_TABLE (MADT)
+      Say Y here if you want to support madt table.
+
+config MCFG_TABLE
+    bool "support MCFG (PCI_EXPRESS_MEMORY_MAPPED_ADDR_TABLE) TABLE"
+    depends on ARM
+    help
+      PCI_EXPRESS_MEMORY_MAPPED_ADDR_TABLE (MCFG)
+      Say Y here if you want to support mcfg table.
+
+config IORT_TABLE
+    bool "support IORT (IO_REMAPPING_TABLE) TABLE"
+    depends on ARM
+    help
+      IO_REMAPPING_TABLE (IORT)
+      Say Y here if you want to support iort table.
+
+config SPCR_TABLE
+    bool "support SPCR (SERIAL_PORT_CONSOLE_REDIRECTION_TABLE) TABLE"
+    depends on ARM
+    help
+      SERIAL_PORT_CONSOLE_REDIRECTION_TABLE (SPCR)
+      Say Y here if you want to support spcr table.
+
+endif
+
 config SEMIHOSTING
 	bool "support boot from semihosting"
 	help
diff --git a/arch/arm/include/asm/acpi_table.h b/arch/arm/include/asm/acpi_table.h
new file mode 100644
index 0000000..ccd9b2c
--- /dev/null
+++ b/arch/arm/include/asm/acpi_table.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2019, PHYTIUM <@phytium.com.cn>
+ * Steven Hao <liuhao@phytium.com.cn>
+ */
+
+#ifndef __ASM_ACPI_TABLE_H__
+#define __ASM_ACPI_TABLE_H__
+
+extern const unsigned char DsdtAmlCode[];
+extern const unsigned char SsdtAmlCode[];
+
+extern unsigned char *rsdp_data;
+extern unsigned char *rsdt_data;
+extern unsigned char *xsdt_data;
+extern unsigned char *fadt_data;
+extern unsigned char *madt_data;
+extern unsigned char *gtdt_data;
+extern unsigned char *mcfg_data;
+extern unsigned char *spcr_data;
+extern unsigned char *iort_data;
+
+extern unsigned char *array_acpi_table_address[32];
+extern unsigned char  acpi_table_count;
+
+/* These can be used by the target port */
+ulong write_acpi_tables(ulong start);
+
+void register_acpi_table_data(void);
+
+void dynamic_modify_fadt_table(void *table);
+void dynamic_modify_gtdt_table(void *table);
+void dynamic_modify_madt_table(void *table);
+void dynamic_modify_mcfg_table(void *table);
+void dynamic_modify_spcr_table(void *table);
+void dynamic_modify_iort_table(void *table);
+
+#endif
+
diff --git a/arch/arm/include/asm/acpi_table/acpi61.h b/arch/arm/include/asm/acpi_table/acpi61.h
new file mode 100644
index 0000000..daf715d
--- /dev/null
+++ b/arch/arm/include/asm/acpi_table/acpi61.h
@@ -0,0 +1,755 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Based on acpi61.h from edk2
+ *
+ * (C) Copyright 2019
+ * Phytium Technology Ltd <www.phytium.com>
+ * Steven Hao <liuhao@phytium.com.cn>
+ */
+
+#ifndef _ACPI_6_1_H_
+#define _ACPI_6_1_H_
+
+#include <asm/acpi_table/arm_platform.h>
+
+/*
+ * Ensure proper structure formats
+ */
+#pragma pack(1)
+
+/*
+ * The common ACPI description table header.
+ * This structure prefaces most ACPI tables.
+ */
+struct efi_acpi_description_header {
+	u32     signature;
+	u32     length;
+	u8      revision;
+	u8      checksum;
+	u8      oem_id[6];
+	u64     oem_table_id;
+	u32     oem_revision;
+	u32     creator_id;
+	u32     creator_revision;
+};
+
+/*
+ * General use definitions
+ */
+#define EFI_ACPI_RESERVED_BYTE  0x00
+#define EFI_ACPI_RESERVED_WORD  0x0000
+#define EFI_ACPI_RESERVED_DWORD 0x00000000
+#define EFI_ACPI_RESERVED_QWORD 0x0000000000000000
+
+/*
+ * ACPI 6.1 Generic Address Space definition
+ */
+struct efi_acpi_6_1_generic_address_structure {
+	u8		address_space_id;
+	u8		register_bit_width;
+	u8		register_bit_offset;
+	u8		access_size;
+	u64		address;
+};
+
+/*
+ * Generic Address Space Address IDs
+ */
+#define EFI_ACPI_6_1_SYSTEM_MEMORY              0
+#define EFI_ACPI_6_1_SYSTEM_IO                  1
+#define EFI_ACPI_6_1_PCI_CONFIGURATION_SPACE    2
+#define EFI_ACPI_6_1_EMBEDDED_CONTROLLER        3
+#define EFI_ACPI_6_1_SMBUS                      4
+#define EFI_ACPI_6_1_PLATFORM_COMMUNICATION_CHANNEL  0x0A
+#define EFI_ACPI_6_1_FUNCTIONAL_FIXED_HARDWARE       0x7F
+
+/*
+ * Generic Address Space Access Sizes
+ */
+#define EFI_ACPI_6_1_UNDEFINED  0
+#define EFI_ACPI_6_1_BYTE       1
+#define EFI_ACPI_6_1_WORD       2
+#define EFI_ACPI_6_1_DWORD      3
+#define EFI_ACPI_6_1_QWORD      4
+
+/*
+ * ACPI 6.1 table structures
+ */
+
+/*
+ * Root System Description Pointer Structure (RSDP)
+ */
+struct efi_acpi_6_1_root_system_description_pointer {
+	u64		signature;
+	u8		checksum;
+	u8		oem_id[6];
+	u8		revision;
+	u32		rsdt_address;
+	u32		length;
+	u64		xsdt_address;
+	u8		extended_checksum;
+	u8		reserved[3];
+};
+
+/*
+ * RSD_PTR Revision (as defined in ACPI 6.1 spec.)
+ */
+
+/* < ACPISpec (Revision 6.1) says current value is 2 */
+#define EFI_ACPI_6_1_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION 0x02
+
+/*
+ * Common table header, this prefaces all ACPI tables, including FACS, but
+ * excluding the RSD PTR structure
+ */
+struct efi_acpi_6_1_common_header {
+	u32		signature;
+	u32		length;
+};
+
+/*
+ * Root System Description Table
+ * No definition needed as it is a common description table header,
+ * the same with EFI_ACPI_DESCRIPTION_HEADER,
+ * followed by a variable number of UINT32 table pointers.
+ */
+#define MAX_ACPI_62_TABLES		32
+
+struct efi_acpi_6_1_root_system_description_table {
+	struct efi_acpi_description_header	header;
+	u32		entry[MAX_ACPI_62_TABLES];
+};
+
+/*
+ * RSDT Revision (as defined in ACPI 6.1 spec.)
+ */
+#define EFI_ACPI_6_1_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01
+
+/*
+ * Extended System Description Table
+ * No definition needed as it is a common description table header,
+ * the same with EFI_ACPI_DESCRIPTION_HEADER,
+ * followed by a variable number of UINT64 table pointers.
+ */
+struct efi_acpi_6_1_extended_system_description_table {
+	struct efi_acpi_description_header	header;
+	u64		entry[MAX_ACPI_62_TABLES];
+};
+
+/*
+ * XSDT Revision (as defined in ACPI 6.1 spec.)
+ */
+#define EFI_ACPI_6_1_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01
+
+/*
+ * Fixed ACPI Description Table Structure (FADT)
+ */
+struct efi_acpi_6_1_fixed_acpi_description_table {
+	struct efi_acpi_description_header	header;
+	u32		firmware_ctrl;
+	u32		dsdt;
+	u8		reserved0;
+	u8		preferred_pm_profile;
+	u16		sci_int;
+	u32		smi_cmd;
+	u8		acpi_enable;
+	u8		acpi_disable;
+	u8		s4_bios_req;
+	u8		pstate_cnt;
+	u32		pm1a_evt_blk;
+	u32		pm1b_evt_blk;
+	u32		pm1a_cnt_blk;
+	u32		pm1b_cnt_blk;
+	u32		pm2_cnt_blk;
+	u32		pm_tmr_blk;
+	u32		gpe0_blk;
+	u32		gpe1_blk;
+	u8		pm1_evt_len;
+	u8		pm1_cnt_len;
+	u8		pm2_cnt_len;
+	u8		pm_tmr_len;
+	u8		gpe0_blk_len;
+	u8		gpe1_blk_len;
+	u8		gpe1_base;
+	u8		cst_cnt;
+	u16		plvl2_lat;
+	u16		plvl3_lat;
+	u16		flush_size;
+	u16		flush_stride;
+	u8		duty_offset;
+	u8		duty_width;
+	u8		day_alrm;
+	u8		mon_alrm;
+	u8		century;
+	u16		ia_pc_boot_arch;
+	u8		reserved1;
+	u32		flags;
+	struct efi_acpi_6_1_generic_address_structure	reset_reg;
+	u8		reset_value;
+	u16		arm_boot_arch;
+	u8		minor_version;
+	u64		x_firmware_ctrl;
+	u64		x_dsdt;
+	struct efi_acpi_6_1_generic_address_structure	x_pm1a_evt_blk;
+	struct efi_acpi_6_1_generic_address_structure	x_pm1b_evt_blk;
+	struct efi_acpi_6_1_generic_address_structure	x_pm1a_cnt_blk;
+	struct efi_acpi_6_1_generic_address_structure	x_pm1b_cnt_blk;
+	struct efi_acpi_6_1_generic_address_structure	x_pm2_cnt_blk;
+	struct efi_acpi_6_1_generic_address_structure	x_pm_tmr_blk;
+	struct efi_acpi_6_1_generic_address_structure	x_gpe0_blk;
+	struct efi_acpi_6_1_generic_address_structure	x_gpe1_blk;
+	struct efi_acpi_6_1_generic_address_structure	sleep_control_reg;
+	struct efi_acpi_6_1_generic_address_structure	sleep_status_reg;
+	u64		hypervisor_vendor_identity;
+};
+
+/*
+ * FADT Version (as defined in ACPI 6.1 spec.)
+ */
+#define EFI_ACPI_6_1_FIXED_ACPI_DESCRIPTION_TABLE_REVISION  0x06
+#define EFI_ACPI_6_1_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION  0x01
+
+/*
+ * Fixed ACPI Description Table Preferred Power Management Profile
+ */
+#define EFI_ACPI_6_1_PM_PROFILE_UNSPECIFIED         0
+#define EFI_ACPI_6_1_PM_PROFILE_DESKTOP             1
+#define EFI_ACPI_6_1_PM_PROFILE_MOBILE              2
+#define EFI_ACPI_6_1_PM_PROFILE_WORKSTATION         3
+#define EFI_ACPI_6_1_PM_PROFILE_ENTERPRISE_SERVER   4
+#define EFI_ACPI_6_1_PM_PROFILE_SOHO_SERVER         5
+#define EFI_ACPI_6_1_PM_PROFILE_APPLIANCE_PC        6
+#define EFI_ACPI_6_1_PM_PROFILE_PERFORMANCE_SERVER  7
+#define EFI_ACPI_6_1_PM_PROFILE_TABLET              8
+
+/*
+ * Fixed ACPI Description Table Boot Architecture Flags
+ * All other bits are reserved and must be set to 0.
+ */
+#define EFI_ACPI_6_1_LEGACY_DEVICES              BIT0
+#define EFI_ACPI_6_1_8042                        BIT1
+#define EFI_ACPI_6_1_VGA_NOT_PRESENT             BIT2
+#define EFI_ACPI_6_1_MSI_NOT_SUPPORTED           BIT3
+#define EFI_ACPI_6_1_PCIE_ASPM_CONTROLS          BIT4
+#define EFI_ACPI_6_1_CMOS_RTC_NOT_PRESENT        BIT5
+
+/*
+ * Fixed ACPI Description Table Arm Boot Architecture Flags
+ * All other bits are reserved and must be set to 0.
+ */
+#define EFI_ACPI_6_1_ARM_PSCI_COMPLIANT              BIT0
+#define EFI_ACPI_6_1_ARM_PSCI_USE_HVC                BIT1
+
+/*
+ * Fixed ACPI Description Table Fixed Feature Flags
+ * All other bits are reserved and must be set to 0.
+ */
+#define EFI_ACPI_6_1_WBINVD                                 BIT0
+#define EFI_ACPI_6_1_WBINVD_FLUSH                           BIT1
+#define EFI_ACPI_6_1_PROC_C1                                BIT2
+#define EFI_ACPI_6_1_P_LVL2_UP                              BIT3
+#define EFI_ACPI_6_1_PWR_BUTTON                             BIT4
+#define EFI_ACPI_6_1_SLP_BUTTON                             BIT5
+#define EFI_ACPI_6_1_FIX_RTC                                BIT6
+#define EFI_ACPI_6_1_RTC_S4                                 BIT7
+#define EFI_ACPI_6_1_TMR_VAL_EXT                            BIT8
+#define EFI_ACPI_6_1_DCK_CAP                                BIT9
+#define EFI_ACPI_6_1_RESET_REG_SUP                          BIT10
+#define EFI_ACPI_6_1_SEALED_CASE                            BIT11
+#define EFI_ACPI_6_1_HEADLESS                               BIT12
+#define EFI_ACPI_6_1_CPU_SW_SLP                             BIT13
+#define EFI_ACPI_6_1_PCI_EXP_WAK                            BIT14
+#define EFI_ACPI_6_1_USE_PLATFORM_CLOCK                     BIT15
+#define EFI_ACPI_6_1_S4_RTC_STS_VALID                       BIT16
+#define EFI_ACPI_6_1_REMOTE_POWER_ON_CAPABLE                BIT17
+#define EFI_ACPI_6_1_FORCE_APIC_CLUSTER_MODEL               BIT18
+#define EFI_ACPI_6_1_FORCE_APIC_PHYSICAL_DESTINATION_MODE   BIT19
+#define EFI_ACPI_6_1_HW_REDUCED_ACPI                        BIT20
+#define EFI_ACPI_6_1_LOW_POWER_S0_IDLE_CAPABLE              BIT21
+
+/*
+ * Multiple APIC Description Table header definition.  The rest of the table
+ * must be defined in a platform specific manner.
+ */
+struct efi_acpi_6_1_multiple_apic_description_table_header {
+	struct efi_acpi_description_header	header;
+	u32		local_apic_address;
+	u32		flags;
+};
+
+/*
+ * MADT Revision (as defined in ACPI 6.1 spec.)
+ */
+#define EFI_ACPI_6_1_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x04
+
+/*
+ * Multiple APIC Flags
+ * All other bits are reserved and must be set to 0.
+ */
+#define EFI_ACPI_6_1_PCAT_COMPAT         BIT0
+
+/*
+ * Multiple APIC Description Table APIC structure types
+ * All other values between 0x0D and 0x7F are reserved and
+ * will be ignored by OSPM. 0x80 ~ 0xFF are reserved for OEM.
+ */
+#define EFI_ACPI_6_1_PROCESSOR_LOCAL_APIC           0x00
+#define EFI_ACPI_6_1_IO_APIC                        0x01
+#define EFI_ACPI_6_1_INTERRUPT_SOURCE_OVERRIDE      0x02
+#define EFI_ACPI_6_1_NON_MASKABLE_INTERRUPT_SOURCE  0x03
+#define EFI_ACPI_6_1_LOCAL_APIC_NMI                 0x04
+#define EFI_ACPI_6_1_LOCAL_APIC_ADDRESS_OVERRIDE    0x05
+#define EFI_ACPI_6_1_IO_SAPIC                       0x06
+#define EFI_ACPI_6_1_LOCAL_SAPIC                    0x07
+#define EFI_ACPI_6_1_PLATFORM_INTERRUPT_SOURCES     0x08
+#define EFI_ACPI_6_1_PROCESSOR_LOCAL_X2APIC         0x09
+#define EFI_ACPI_6_1_LOCAL_X2APIC_NMI               0x0A
+#define EFI_ACPI_6_1_GIC                            0x0B
+#define EFI_ACPI_6_1_GICD                           0x0C
+#define EFI_ACPI_6_1_GIC_MSI_FRAME                  0x0D
+#define EFI_ACPI_6_1_GICR                           0x0E
+#define EFI_ACPI_6_1_GIC_ITS                        0x0F
+
+/*
+ * APIC Structure Definitions
+ */
+
+/*
+ * Processor Local APIC Structure Definition
+ */
+struct efi_acpi_6_1_processor_local_apic_structure {
+	u8		type;
+	u8		length;
+	u8		acpi_processor_uid;
+	u8		apic_id;
+	u32		flags;
+};
+
+/*
+ * Local APIC Flags.  All other bits are reserved and must be 0.
+ */
+#define EFI_ACPI_6_1_LOCAL_APIC_ENABLED        BIT0
+
+/*
+ * IO APIC Structure
+ */
+struct efi_acpi_6_1_io_apic_structure {
+	u8		type;
+	u8		length;
+	u8		io_apic_id;
+	u8		reserved;
+	u32		io_apic_address;
+	u32		global_system_interrupt_base;
+};
+
+/*
+ * Interrupt Source Override Structure
+ */
+struct efi_acpi_6_1_interrupt_source_override_structure {
+	u8		type;
+	u8		length;
+	u8		bus;
+	u8		source;
+	u32		global_system_interrupt;
+	u16		flags;
+};
+
+/*
+ * Platform Interrupt Sources Structure Definition
+ */
+struct efi_acpi_6_1_platform_interrupt_apic_structure {
+	u8		type;
+	u8		length;
+	u16		flags;
+	u8		interrupt_type;
+	u8		processor_id;
+	u8		processor_eid;
+	u8		io_sapic_vector;
+	u32		global_system_interrupt;
+	u32		platform_interrupt_source_flags;
+	u8		cpei_processor_override;
+	u8		reserved[31];
+};
+
+/*
+ * MPS INTI flags.
+ * All other bits are reserved and must be set to 0.
+ */
+#define EFI_ACPI_6_1_POLARITY      (3 << 0)
+#define EFI_ACPI_6_1_TRIGGER_MODE  (3 << 2)
+
+/*
+ * Non-Maskable Interrupt Source Structure
+ */
+struct efi_acpi_6_1_non_maskable_interrupt_source_structure {
+	u8		type;
+	u8		length;
+	u16		flags;
+	u32		global_system_interrupt;
+};
+
+/*
+ * Local APIC NMI Structure
+ */
+struct efi_acpi_6_1_local_apic_nmi_structure {
+	u8		type;
+	u8		length;
+	u8		acpi_processor_uid;
+	u16		flags;
+	u8		local_apic_lint;
+};
+
+/*
+ * Local APIC Address Override Structure
+ */
+struct efi_acpi_6_1_local_apic_address_override_structure {
+	u8		type;
+	u8		length;
+	u16		reserved;
+	u64		local_apic_address;
+};
+
+/*
+ * IO SAPIC Structure
+ */
+struct efi_acpi_6_1_io_sapic_structure {
+	u8		type;
+	u8		length;
+	u8		io_apic_id;
+	u8		reserved;
+	u32		global_system_interrupt_base;
+	u64		io_sapic_address;
+};
+
+/*
+ * Local SAPIC Structure
+ * This struct followed by a null-terminated ASCII string -
+ * ACPI Processor UID String
+ */
+struct efi_acpi_6_1_processor_local_sapic_structure {
+	u8		type;
+	u8		length;
+	u8		acpi_processor_id;
+	u8		local_sapic_id;
+	u8		local_sapic_eid;
+	u8		reserved[3];
+	u32		flags;
+	u32		ACPI_processor_UID_value;
+};
+
+/*
+ * Platform Interrupt Sources Structure
+ */
+struct efi_acpi_6_1_platform_interrupt_sources_structure {
+	u8		type;
+	u8		length;
+	u16		flags;
+	u8		interrupt_type;
+	u8		processor_id;
+	u8		processor_eid;
+	u8		io_sapic_vector;
+	u32		global_system_interrupt;
+	u32		platform_interrupt_source_flags;
+};
+
+/*
+ * Platform Interrupt Source Flags.
+ * All other bits are reserved and must be set to 0.
+ */
+#define EFI_ACPI_6_1_CPEI_PROCESSOR_OVERRIDE          BIT0
+
+/*
+ * Processor Local x2APIC Structure Definition
+ */
+struct efi_acpi_6_1_processor_local_x2apic_structure {
+	u8		type;
+	u8		length;
+	u8		reserved[2];
+	u32		x2_apic_id;
+	u32		flags;
+	u32		acpi_processor_uid;
+};
+
+/*
+ * Local x2APIC NMI Structure
+ */
+struct efi_acpi_6_1_local_x2apic_nmi_structure {
+	u8		type;
+	u8		length;
+	u16		flags;
+	u32		acpi_processor_uid;
+	u8		local_x2_apic_lint;
+	u8		reserved[3];
+};
+
+/*
+ * GIC Structure
+ */
+struct efi_acpi_6_1_gic_structure {
+	u8		type;
+	u8		length;
+	u16		reserved;
+	u32		CPU_interface_number;
+	u32		acpi_processor_uid;
+	u32		flags;
+	u32		parking_protocol_version;
+	u32		performance_interrupt_gsiv;
+	u64		parked_address;
+	u64		physical_base_address;
+	u64		GICV;
+	u64		GICH;
+	u32		VGIC_maintenance_interrupt;
+	u64		GICR_base_address;
+	u64		MPIDR;
+	u8		processor_power_efficiency_class;
+	u8		reserved2[3];
+};
+
+/*
+ * GIC Flags.  All other bits are reserved and must be 0.
+ */
+#define EFI_ACPI_6_1_GIC_ENABLED                              BIT0
+#define EFI_ACPI_6_1_PERFORMANCE_INTERRUPT_MODEL              BIT1
+#define EFI_ACPI_6_1_VGIC_MAINTENANCE_INTERRUPT_MODE_FLAGS    BIT2
+
+/*
+ * GIC Distributor Structure
+ */
+struct efi_acpi_6_1_gic_distributor_structure {
+	u8		type;
+	u8		length;
+	u16		reserved1;
+	u32		gic_id;
+	u64		physical_base_address;
+	u32		system_vector_base;
+	u8		gic_version;
+	u8		reserved2[3];
+};
+
+/*
+ * GIC Version
+ */
+#define EFI_ACPI_6_1_GIC_V1                                   0x01
+#define EFI_ACPI_6_1_GIC_V2                                   0x02
+#define EFI_ACPI_6_1_GIC_V3                                   0x03
+#define EFI_ACPI_6_1_GIC_V4                                   0x04
+
+/*
+ * GIC MSI Frame Structure
+ */
+struct efi_acpi_6_1_gic_msi_frame_structure {
+	u8		type;
+	u8		length;
+	u16		reserved1;
+	u32		gic_msi_frame_id;
+	u64		physical_base_address;
+	u32		flags;
+	u16		SPI_count;
+	u16		SPI_base;
+};
+
+/*
+ * GIC MSI Frame Flags.  All other bits are reserved and must be 0.
+ */
+#define EFI_ACPI_6_1_SPI_COUNT_BASE_SELECT                    BIT0
+
+/*
+ * GICR Structure
+ */
+struct efi_acpi_6_1_gicr_structure {
+	u8		type;
+	u8		length;
+	u16		reserved;
+	u64		discovery_range_base_address;
+	u32		discovery_range_length;
+};
+
+/*
+ * GIC Interrupt Translation Service Structure
+ */
+struct efi_acpi_6_1_gic_its_structure {
+	u8		type;
+	u8		length;
+	u16		reserved;
+	u32		gic_its_id;
+	u64		physical_base_address;
+	u32		reserved2;
+};
+
+/*
+ * Generic Timer Description Table definition.
+ */
+struct efi_acpi_6_1_generic_timer_description_table {
+	struct efi_acpi_description_header	header;
+	u64		cnt_control_base_physical_address;
+	u32		reserved;
+	u32		secure_pl1_timer_GSIV;
+	u32		secure_pl1_timer_flags;
+	u32		non_secure_pl1_timer_GSIV;
+	u32		non_secure_pl1_timer_flags;
+	u32		virtual_timer_GSIV;
+	u32		virtual_timer_flags;
+	u32		non_secure_pl2_timer_GSIV;
+	u32		non_secure_pl2_timer_flags;
+	u64		cnt_read_base_physical_address;
+	u32		platform_timer_count;
+	u32		platform_timer_offset;
+};
+
+/*
+ * GTDT Version (as defined in ACPI 6.1 spec.)
+ */
+#define EFI_ACPI_6_1_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION 0x02
+
+/*
+ * Timer Flags.  All other bits are reserved and must be 0.
+ */
+#define EFI_ACPI_6_1_GTDT_TIMER_FLAG_TIMER_INTERRUPT_MODE          BIT0
+#define EFI_ACPI_6_1_GTDT_TIMER_FLAG_TIMER_INTERRUPT_POLARITY      BIT1
+#define EFI_ACPI_6_1_GTDT_TIMER_FLAG_ALWAYS_ON_CAPABILITY          BIT2
+
+/*
+ * Platform Timer Type
+ */
+#define EFI_ACPI_6_1_GTDT_GT_BLOCK                       0
+#define EFI_ACPI_6_1_GTDT_SBSA_GENERIC_WATCHDOG          1
+
+/*
+ * GT Block Structure
+ */
+struct efi_acpi_6_1_gtdt_gt_block_structure {
+	u8		type;
+	u16		length;
+	u8		reserved;
+	u64		cnt_ctl_base;
+	u32		GT_block_timer_count;
+	u32		GT_block_timer_offset;
+};
+
+/*
+ * GT Block Timer Structure
+ */
+struct efi_acpi_6_1_gtdt_gt_block_timer_structure {
+	u8		GT_frame_number;
+	u8		reserved[3];
+	u64		cnt_base_X;
+	u64		cnt_el0_base_X;
+	u32		GT_x_physical_timer_GSIV;
+	u32		GT_x_physical_timer_flags;
+	u32		GT_x_virtual_timer_GSIV;
+	u32		GT_x_virtual_timer_flags;
+	u32		GT_x_common_flags;
+};
+
+/*
+ * GT Block Physical Timers and Virtual Timers Flags.
+ * All other bits are reserved and must be 0.
+ */
+#define EFI_ACPI_6_1_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_MODE       BIT0
+#define EFI_ACPI_6_1_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_POLARITY   BIT1
+
+/*
+ * Common Flags Flags.  All other bits are reserved and must be 0.
+ */
+#define EFI_ACPI_6_1_GTDT_GT_BLOCK_COMMON_FLAG_SECURE_TIMER              BIT0
+#define EFI_ACPI_6_1_GTDT_GT_BLOCK_COMMON_FLAG_ALWAYS_ON_CAPABILITY      BIT1
+
+/*
+ * SBSA Generic Watchdog Structure
+ */
+struct efi_acpi_6_1_gtdt_sbsa_generic_watchdog_structure {
+	u8		type;
+	u16		length;
+	u8		reserved;
+	u64		refresh_frame_physical_address;
+	u64		watchdog_control_frame_physical_address;
+	u32		watchdog_timer_GSIV;
+	u32		watchdog_timer_flags;
+};
+
+/*
+ * SBSA Generic Watchdog Timer Flags.  All other bits are reserved
+ * and must be 0.
+ */
+#define EFI_ACPI_6_1_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_MODE  \
+						BIT0
+#define EFI_ACPI_6_1_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_POLARITY\
+						BIT1
+#define EFI_ACPI_6_1_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_SECURE_TIMER            \
+						BIT2
+
+/*
+ * table signatures
+ */
+
+/*
+ * "RSD PTR " Root System Description Pointer
+ */
+#define EFI_ACPI_6_1_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE \
+			SIGNATURE_64('R', 'S', 'D', ' ', 'P', 'T', 'R', ' ')
+
+/*
+ * "APIC" Multiple APIC Description Table
+ */
+#define EFI_ACPI_6_1_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE \
+					SIGNATURE_32('A', 'P', 'I', 'C')
+
+/*
+ * "DSDT" Differentiated System Description Table
+ */
+#define EFI_ACPI_6_1_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE \
+					SIGNATURE_32('D', 'S', 'D', 'T')
+
+/*
+ * "FACP" Fixed ACPI Description Table
+ */
+#define EFI_ACPI_6_1_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE \
+					SIGNATURE_32('F', 'A', 'C', 'P')
+
+/*
+ * "GTDT" Generic Timer Description Table
+ */
+#define EFI_ACPI_6_1_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE \
+					SIGNATURE_32('G', 'T', 'D', 'T')
+
+/*
+ * "RSDT" Root System Description Table
+ */
+#define EFI_ACPI_6_1_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE \
+					SIGNATURE_32('R', 'S', 'D', 'T')
+
+/*
+ * "SSDT" Secondary System Description Table
+ */
+#define EFI_ACPI_6_1_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE \
+					SIGNATURE_32('S', 'S', 'D', 'T')
+
+/*
+ * "XSDT" Extended System Description Table
+ */
+#define EFI_ACPI_6_1_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  \
+					SIGNATURE_32('X', 'S', 'D', 'T')
+
+/*
+ * "IORT" I/O Remapping Table
+ */
+#define EFI_ACPI_6_1_IO_REMAPPING_TABLE_SIGNATURE \
+					SIGNATURE_32('I', 'O', 'R', 'T')
+
+/*
+ * "MCFG" PCI Express Memory Mapped
+ * Configuration Space Base Address Description Table
+ */
+#define EFI_ACPI_6_1_PCI_EXPRESS_MEMORY_MAPPED_ADDR_TABLE_SIGNATURE \
+					SIGNATURE_32('M', 'C', 'F', 'G')
+
+/*
+ * "SPCR" Serial Port Concole Redirection Table
+ */
+#define EFI_ACPI_6_1_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE \
+					SIGNATURE_32('S', 'P', 'C', 'R')
+
+#pragma pack()
+
+#endif
+
diff --git a/arch/arm/include/asm/acpi_table/acpi_lib.h b/arch/arm/include/asm/acpi_table/acpi_lib.h
new file mode 100644
index 0000000..f3404e9
--- /dev/null
+++ b/arch/arm/include/asm/acpi_table/acpi_lib.h
@@ -0,0 +1,89 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Based on acpi_lib.h from edk2
+ *
+ * (C) Copyright 2019
+ * Phytium Technology Ltd <www.phytium.com>
+ * Steven Hao <liuhao@phytium.com.cn>
+ */
+
+#ifndef __ACPI_LIB_H__
+#define __ACPI_LIB_H__
+
+#include <asm/acpi_table/acpi61.h>
+
+/*
+ * Macros for the Generic Address Space
+ */
+#define null_gas              \
+	    { EFI_ACPI_6_1_SYSTEM_MEMORY, 0, 0, EFI_ACPI_6_1_UNDEFINED, 0L }
+#define arm_gas8(address)      \
+	    { EFI_ACPI_6_1_SYSTEM_MEMORY, 8, 0, EFI_ACPI_6_1_BYTE, address }
+#define arm_gas16(address)     \
+	    { EFI_ACPI_6_1_SYSTEM_MEMORY, 16, 0, EFI_ACPI_6_1_WORD, address }
+#define arm_gas32(address)     \
+	    { EFI_ACPI_6_1_SYSTEM_MEMORY, 32, 0, EFI_ACPI_6_1_DWORD, address }
+#define arm_gasn(address)      \
+	    { EFI_ACPI_6_1_SYSTEM_MEMORY, 0, 0, EFI_ACPI_6_1_DWORD, address }
+
+#define efi_acpi_6_1_gic_its_init(gic_its_hw_id, gic_its_base) {\
+	EFI_ACPI_6_1_GIC_ITS,\
+	sizeof(struct efi_acpi_6_1_gic_its_structure),\
+	EFI_ACPI_RESERVED_WORD,\
+	gic_its_hw_id, gic_its_base, EFI_ACPI_RESERVED_DWORD\
+}
+
+#define efi_acpi_6_1_gicc_affinity_structure_init(\
+	proximity_domain, ACPI_processor_UID, flags, clock_domain) {\
+	3, sizeof(struct efi_acpi_6_1_gicc_affinity_structure),\
+	proximity_domain,\
+	ACPI_processor_UID, flags, clock_domain\
+}
+
+#define efi_acpi_6_1_processor_affinity_structure_init(\
+	proximity_domain, apic_id, flags, clock_domain) {\
+	0,\
+sizeof(struct efi_acpi_6_1_processor_local_apic_sapic_affinity_structure),\
+	proximity_domain, apic_id, flags, 0x00, {0, 0, 0}, clock_domain\
+}
+
+#define efi_acpi_6_1_memory_affinity_structure_init(\
+	proximity_domain, address_base_low, address_base_high,\
+	length_low, length_high, flags) {\
+	1, sizeof(struct efi_acpi_6_1_memory_affinity_structure),\
+	proximity_domain, EFI_ACPI_RESERVED_WORD,\
+	address_base_low, address_base_high, length_low, length_high,\
+	EFI_ACPI_RESERVED_DWORD, flags,\
+	EFI_ACPI_RESERVED_QWORD\
+}
+
+#define efi_acpi_6_1_gicc_structure_init(\
+	gic_id, acpi_cpu_uid, mpidr, flags, pmu_irq,\
+	gic_base, gicV_base, gicH_base, gsiv_id, gicR_base,\
+	processor_power_efficiency_class) { \
+	EFI_ACPI_6_1_GIC, sizeof(struct efi_acpi_6_1_gic_structure),\
+	0x0000, gic_id, acpi_cpu_uid, \
+	flags, 0, pmu_irq, 0, gic_base, gicV_base, gicH_base,\
+	gsiv_id, gicR_base, mpidr, processor_power_efficiency_class,\
+	{ \
+		0,\
+		0,\
+		0\
+	} \
+}
+
+#define efi_acpi_6_1_gic_distributor_init(\
+	gic_dist_hw_id, gic_dist_base, gic_dist_vector, gic_version) {\
+	EFI_ACPI_6_1_GICD,\
+	sizeof(struct efi_acpi_6_1_gic_distributor_structure),\
+	EFI_ACPI_RESERVED_WORD,\
+	gic_dist_hw_id, gic_dist_base, gic_dist_vector, gic_version,\
+	{ \
+		EFI_ACPI_RESERVED_BYTE,\
+		EFI_ACPI_RESERVED_BYTE,\
+		EFI_ACPI_RESERVED_BYTE\
+	} \
+}
+
+#endif
+
diff --git a/arch/arm/include/asm/acpi_table/arm_platform.h b/arch/arm/include/asm/acpi_table/arm_platform.h
new file mode 100644
index 0000000..8009daf
--- /dev/null
+++ b/arch/arm/include/asm/acpi_table/arm_platform.h
@@ -0,0 +1,93 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Based on arm_platform.h from edk2
+ *
+ * (C) Copyright 2019
+ * Phytium Technology Ltd <www.phytium.com>
+ * Steven Hao <liuhao@phytium.com.cn>
+ */
+
+#ifndef __ARM_PLATFORM_H__
+#define __ARM_PLATFORM_H__
+
+/*
+ * ACPI table information used to initialize tables.
+ */
+typedef unsigned long long	u64;
+typedef unsigned int		u32;
+typedef unsigned short		u16;
+typedef unsigned char		u8;
+
+#define  BIT0     0x00000001
+#define  BIT1     0x00000002
+#define  BIT2     0x00000004
+#define  BIT3     0x00000008
+#define  BIT4     0x00000010
+#define  BIT5     0x00000020
+#define  BIT6     0x00000040
+#define  BIT7     0x00000080
+#define  BIT8     0x00000100
+#define  BIT9     0x00000200
+#define  BIT10    0x00000400
+#define  BIT11    0x00000800
+#define  BIT12    0x00001000
+#define  BIT13    0x00002000
+#define  BIT14    0x00004000
+#define  BIT15    0x00008000
+#define  BIT16    0x00010000
+#define  BIT17    0x00020000
+#define  BIT18    0x00040000
+#define  BIT19    0x00080000
+#define  BIT20    0x00100000
+#define  BIT21    0x00200000
+#define  BIT22    0x00400000
+#define  BIT23    0x00800000
+#define  BIT24    0x01000000
+#define  BIT25    0x02000000
+#define  BIT26    0x04000000
+#define  BIT27    0x08000000
+#define  BIT28    0x10000000
+#define  BIT29    0x20000000
+#define  BIT30    0x40000000
+#define  BIT31    0x80000000
+#define  BIT32    0x0000000100000000ULL
+#define  BIT33    0x0000000200000000ULL
+#define  BIT34    0x0000000400000000ULL
+#define  BIT35    0x0000000800000000ULL
+#define  BIT36    0x0000001000000000ULL
+#define  BIT37    0x0000002000000000ULL
+#define  BIT38    0x0000004000000000ULL
+#define  BIT39    0x0000008000000000ULL
+#define  BIT40    0x0000010000000000ULL
+#define  BIT41    0x0000020000000000ULL
+#define  BIT42    0x0000040000000000ULL
+#define  BIT43    0x0000080000000000ULL
+#define  BIT44    0x0000100000000000ULL
+#define  BIT45    0x0000200000000000ULL
+#define  BIT46    0x0000400000000000ULL
+#define  BIT47    0x0000800000000000ULL
+#define  BIT48    0x0001000000000000ULL
+#define  BIT49    0x0002000000000000ULL
+#define  BIT50    0x0004000000000000ULL
+#define  BIT51    0x0008000000000000ULL
+#define  BIT52    0x0010000000000000ULL
+#define  BIT53    0x0020000000000000ULL
+#define  BIT54    0x0040000000000000ULL
+#define  BIT55    0x0080000000000000ULL
+#define  BIT56    0x0100000000000000ULL
+#define  BIT57    0x0200000000000000ULL
+#define  BIT58    0x0400000000000000ULL
+#define  BIT59    0x0800000000000000ULL
+#define  BIT60    0x1000000000000000ULL
+#define  BIT61    0x2000000000000000ULL
+#define  BIT62    0x4000000000000000ULL
+#define  BIT63    0x8000000000000000ULL
+
+#define SIGNATURE_16(A, B)		((A) | ((B) << 8))
+#define SIGNATURE_32(A, B, C, D)  \
+	(SIGNATURE_16(A, B) | (SIGNATURE_16(C, D) << 16))
+#define SIGNATURE_64(A, B, C, D, E, F, G, H) \
+	(SIGNATURE_32(A, B, C, D) | ((u64)(SIGNATURE_32(E, F, G, H)) << 32))
+
+#endif
+
diff --git a/arch/arm/include/asm/acpi_table/io_remapping_table.h b/arch/arm/include/asm/acpi_table/io_remapping_table.h
new file mode 100644
index 0000000..9899cfe
--- /dev/null
+++ b/arch/arm/include/asm/acpi_table/io_remapping_table.h
@@ -0,0 +1,179 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Based on io_remapping_table.h from edk2
+ *
+ * (C) Copyright 2019
+ * Phytium Technology Ltd <www.phytium.com>
+ * Steven Hao <liuhao@phytium.com.cn>
+ */
+
+#ifndef __IO_REMAPPING_TABLE_H__
+#define __IO_REMAPPING_TABLE_H__
+
+#include <asm/acpi_table/acpi61.h>
+
+#define EFI_ACPI_IO_REMAPPING_TABLE_REVISION        0x0
+
+#define EFI_ACPI_IORT_TYPE_ITS_GROUP                0x0
+#define EFI_ACPI_IORT_TYPE_NAMED_COMP               0x1
+#define EFI_ACPI_IORT_TYPE_ROOT_COMPLEX             0x2
+#define EFI_ACPI_IORT_TYPE_SMMUV1V2                 0x3
+#define EFI_ACPI_IORT_TYPE_SMMUV3                   0x4
+#define EFI_ACPI_IORT_TYPE_PMCG                     0x5
+
+#define EFI_ACPI_IORT_MEM_ACCESS_PROP_CCA           BIT0
+
+#define EFI_ACPI_IORT_MEM_ACCESS_PROP_AH_TR         BIT0
+#define EFI_ACPI_IORT_MEM_ACCESS_PROP_AH_WA         BIT1
+#define EFI_ACPI_IORT_MEM_ACCESS_PROP_AH_RA         BIT2
+#define EFI_ACPI_IORT_MEM_ACCESS_PROP_AH_AHO        BIT3
+
+#define EFI_ACPI_IORT_MEM_ACCESS_FLAGS_CPM          BIT0
+#define EFI_ACPI_IORT_MEM_ACCESS_FLAGS_DACS         BIT1
+
+#define EFI_ACPI_IORT_SMMUV1V2_MODEL_V1             0x0
+#define EFI_ACPI_IORT_SMMUV1V2_MODEL_V2             0x1
+#define EFI_ACPI_IORT_SMMUV1V2_MODEL_MMU400         0x2
+#define EFI_ACPI_IORT_SMMUV1V2_MODEL_MMU500         0x3
+#define EFI_ACPI_IORT_SMMUV1V2_MODEL_MMU401         0x4
+#define EFI_ACPI_IORT_SMMUV1V2_MODEL_CAVIUM_THX_V2  0x5
+
+#define EFI_ACPI_IORT_SMMUV1V2_FLAG_DVM             BIT0
+#define EFI_ACPI_IORT_SMMUV1V2_FLAG_COH_WALK        BIT1
+
+#define EFI_ACPI_IORT_SMMUV1V2_INT_FLAG_LEVEL       0x0
+#define EFI_ACPI_IORT_SMMUV1V2_INT_FLAG_EDGE        0x1
+
+#define EFI_ACPI_IORT_SMMUV3_FLAG_COHAC_OVERRIDE    BIT0
+#define EFI_ACPI_IORT_SMMUV3_FLAG_HTTU_OVERRIDE     BIT1
+
+#define EFI_ACPI_IORT_ROOT_COMPLEX_ATS_UNSUPPORTED  0x0
+#define EFI_ACPI_IORT_ROOT_COMPLEX_ATS_SUPPORTED    0x1
+
+#define EFI_ACPI_IORT_ID_MAPPING_FLAGS_SINGLE       BIT0
+
+#pragma pack(1)
+
+/*
+ * Table header
+ */
+struct efi_acpi_6_0_io_remapping_table {
+	struct efi_acpi_description_header	header;
+	u32			num_nodes;
+	u32			node_offset;
+	u32			reserved;
+};
+
+/*
+ * Definition for ID mapping table shared by all node types
+ */
+struct efi_acpi_6_0_io_remapping_id_table {
+	u32			input_base;
+	u32			num_ids;
+	u32			output_base;
+	u32			output_reference;
+	u32			flags;
+};
+
+/*
+ * Node header definition shared by all node types
+ */
+struct efi_acpi_6_0_io_remapping_node {
+	u8			type;
+	u16			length;
+	u8			revision;
+	u32			reserved;
+	u32			num_id_mappings;
+	u32			id_reference;
+};
+
+/*
+ * Node type 0: ITS node
+ */
+struct efi_acpi_6_0_io_remapping_its_node {
+	struct efi_acpi_6_0_io_remapping_node	node;
+	u32						num_its_identifiers;
+};
+
+/*
+ * Node type 1: root complex node
+ */
+struct efi_acpi_6_0_io_remapping_rc_node {
+	struct efi_acpi_6_0_io_remapping_node	node;
+	u32			cache_coherent;
+	u8			allocation_hints;
+	u16			reserved;
+	u8			memory_access_flags;
+	u32			ats_attribute;
+	u32			pci_segment_number;
+};
+
+/*
+ * Node type 2: named component node
+ */
+struct efi_acpi_6_0_io_remapping_named_comp_node {
+	struct efi_acpi_6_0_io_remapping_node	node;
+	u32			flags;
+	u32			cache_coherent;
+	u8			allocation_hints;
+	u16			reserved;
+	u8			memory_access_flags;
+	u8			address_size_limit;
+};
+
+/*
+ * Node type 3: SMMUv1 or SMMUv2 node
+ */
+struct efi_acpi_6_0_io_remapping_smmu_int {
+	u32			interrupt;
+	u32			interrupt_flags;
+};
+
+struct efi_acpi_6_0_io_remapping_smmu_node {
+	struct efi_acpi_6_0_io_remapping_node	node;
+	u64			base;
+	u64			span;
+	u32			model;
+	u32			flags;
+	u32			global_interrupt_array_ref;
+	u32			num_context_interrupts;
+	u32			context_interrupt_array_ref;
+	u32			num_pmu_interrupts;
+	u32			pmu_interrupta_array_ref;
+
+	u32			smmu_nsg_irpt;
+	u32			smmu_nsg_irpt_flags;
+	u32			smmu_nsg_cfg_irpt;
+	u32			smmu_nsg_cfg_irpt_flags;
+};
+
+/*
+ * Node type 4: SMMUv4 node
+ */
+struct efi_acpi_6_0_io_remapping_smmu3_node {
+	struct efi_acpi_6_0_io_remapping_node	node;
+	u64			base;
+	u32			flags;
+	u32			reserved;
+	u64			vatos_address;
+	u32			model;
+	u32			event;
+	u32			pri;
+	u32			gerr;
+	u32			sync;
+};
+
+/*
+ * Node type 5: PMCG node
+ */
+struct efi_acpi_6_0_io_remapping_pmcg_node {
+	struct efi_acpi_6_0_io_remapping_node	node;
+	u64			base;
+	u32			overflow_interrupt_gsiv;
+	u32			node_reference;
+};
+
+#pragma pack()
+
+#endif
+
diff --git a/arch/arm/include/asm/acpi_table/spcr_table.h b/arch/arm/include/asm/acpi_table/spcr_table.h
new file mode 100644
index 0000000..eac5f15
--- /dev/null
+++ b/arch/arm/include/asm/acpi_table/spcr_table.h
@@ -0,0 +1,175 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Based on serial_port_console_redirection.h from edk2
+ *
+ * (C) Copyright 2019
+ * Phytium Technology Ltd <www.phytium.com>
+ * Steven Hao <liuhao@phytium.com.cn>
+ */
+
+#ifndef _SPCR_TABLE_H_
+#define _SPCR_TABLE_H_
+
+#include <asm/acpi_table/acpi61.h>
+
+/*
+ * Ensure proper structure formats
+ */
+#pragma pack(1)
+
+/*
+ * SPCR Revision (defined in spec)
+ */
+#define EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION 0x02
+
+/*
+ * Serial Port Console Redirection Table Format
+ */
+struct efi_acpi_serial_port_console_redirection_table {
+	struct efi_acpi_description_header	header;
+	u8		interface_type;
+	u8		reserved1[3];
+	struct efi_acpi_6_1_generic_address_structure	base_address;
+	u8		interrupt_type;
+	u8		irq;
+	u32		global_system_interrupt;
+	u8		baud_rate;
+	u8		parity;
+	u8		stop_bits;
+	u8		flow_control;
+	u8		terminal_type;
+	u8		reserved2;
+	u16		pci_device_id;
+	u16		pci_vendor_id;
+	u8		pci_bus_number;
+	u8		pci_device_number;
+	u8		pci_function_number;
+	u32		pci_flags;
+	u8		pci_segment;
+	u32		reserved3;
+};
+
+#pragma pack()
+
+/*
+ * SPCR Definitions
+ */
+
+/*
+ * Interface Type
+ */
+
+/*
+ * Full 16550 interface
+ */
+#define EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERFACE_TYPE_16550\
+						0
+/*
+ * Full 16450 interface
+ */
+#define EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERFACE_TYPE_16450\
+						1
+
+/*
+ * The Serial Port Subtypes for ARM are documented in Table 3 of
+ * the DBG2 Specification
+ */
+
+/*
+ * ARM PL011 UART
+ */
+#define \
+EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERFACE_TYPE_ARM_PL011_UART\
+							0x03
+
+/*
+ * ARM SBSA Generic UART (2.x) supporting 32-bit only accesses [deprecated]
+ */
+#define EFI_ACPI_SERIAL_TABLE_INTERFACE_TYPE_ARM_SBSA_UART_2X  0x0d
+
+/*
+ * ARM SBSA Generic UART
+ */
+#define EFI_ACPI_SERIAL_TABLE_INTERFACE_TYPE_ARM_SBSA_UART     0x0e
+
+/*
+ * Interrupt Type
+ */
+
+/*
+ * PC-AT-compatible dual-8259 IRQ interrupt
+ */
+#define EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERRUPT_TYPE_8259\
+						0x1
+/*
+ * I/O APIC interrupt (Global System Interrupt)
+ */
+#define EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERRUPT_TYPE_APIC\
+						0x2
+/*
+ * I/O SAPIC interrupt (Global System Interrupt)
+ */
+#define EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERRUPT_TYPE_SAPIC\
+						0x4
+/*
+ * ARMH GIC interrupt (Global System Interrupt)
+ */
+#define EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERRUPT_TYPE_GIC\
+						0x8
+
+/*
+ * Baud Rate
+ */
+#define EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_9600      3
+#define EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_19200     4
+#define EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_57600     6
+#define EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_115200    7
+
+/*
+ * Parity
+ */
+#define EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_PARITY_NO_PARITY    0
+
+/*
+ * Stop Bits
+ */
+#define EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_STOP_BITS_1         1
+
+/*
+ * Flow Control
+ */
+
+/*
+ * DCD required for transmit
+ */
+#define EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_FLOW_CONTROL_DCD\
+						0x1
+/*
+ * RTS/CTS hardware flow control
+ */
+#define EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_FLOW_CONTROL_RTS_CTS\
+						0x2
+/*
+ *  XON/XOFF software control
+ */
+#define EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_FLOW_CONTROL_XON_XOFF\
+						0x4
+
+/*
+ * Terminal Type
+ */
+#define \
+EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_TERMINAL_TYPE_VT100\
+						0
+#define \
+EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_TERMINAL_TYPE_VT100_PLUS\
+						1
+#define \
+EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_TERMINAL_TYPE_VT_UTF8\
+						2
+#define \
+EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_TERMINAL_TYPE_ANSI\
+						3
+
+#endif
+
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 9de9a9a..39bb105 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -28,6 +28,7 @@ else
 obj-y	+= relocate.o
 endif
 
+obj-$(CONFIG_ARM_ACPI_TABLE) += acpi_table.o
 obj-$(CONFIG_CPU_V7M) += cmd_boot.o
 obj-$(CONFIG_OF_LIBFDT) += bootm-fdt.o
 obj-$(CONFIG_CMD_BOOTI) += bootm.o image.o
diff --git a/arch/arm/lib/acpi_table.c b/arch/arm/lib/acpi_table.c
new file mode 100644
index 0000000..9401955
--- /dev/null
+++ b/arch/arm/lib/acpi_table.c
@@ -0,0 +1,244 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Based on acpi.c from coreboot
+ *
+ * Copyright (C) 2019
+ * Steven Hao <liuhao@phytium.com.cn>
+ */
+
+#include <common.h>
+#include <cpu.h>
+#include <dm.h>
+#include <dm/uclass-internal.h>
+#include <serial.h>
+#include <version.h>
+#include <tables_csum.h>
+#include <asm/acpi_table.h>
+#include <asm/acpi_table/acpi61.h>
+#include <asm/acpi_table/spcr_table.h>
+#include <asm/acpi_table/acpi_lib.h>
+#include <asm/acpi_table/arm_platform.h>
+#include <asm/acpi_table/io_remapping_table.h>
+
+/* record the acpi_table data and count */
+__weak void register_acpi_table_data(void) {}
+
+static void acpi_write_rsdp
+		(struct efi_acpi_6_1_root_system_description_pointer *rsdp,
+		struct efi_acpi_6_1_root_system_description_table *rsdt,
+		struct efi_acpi_6_1_extended_system_description_table *xsdt)
+{
+	u16 rsdp_size =
+		sizeof(struct efi_acpi_6_1_root_system_description_pointer);
+	memcpy(rsdp, rsdp_data, rsdp_size);
+	rsdp->rsdt_address = (u32)(uintptr_t)rsdt;
+	rsdp->xsdt_address = (u64)(u32)(uintptr_t)xsdt;
+
+	/* Calculate checksums */
+	rsdp->checksum = 0;
+	rsdp->extended_checksum = 0;
+	rsdp->checksum = table_compute_checksum((void *)rsdp, 20);
+	rsdp->extended_checksum =
+		table_compute_checksum((void *)rsdp, rsdp_size);
+}
+
+static void
+acpi_write_rsdt(struct efi_acpi_6_1_root_system_description_table *rsdt)
+{
+	memcpy(rsdt, rsdt_data, sizeof(struct efi_acpi_description_header));
+}
+
+static void
+acpi_write_xsdt(struct efi_acpi_6_1_extended_system_description_table *xsdt)
+{
+	memcpy(xsdt, xsdt_data, sizeof(struct efi_acpi_description_header));
+}
+
+/*
+ * Add an ACPI table to the RSDT (and XSDT) structure, recalculate length
+ * and checksum.
+ */
+static void acpi_add_table
+	(struct efi_acpi_6_1_root_system_description_pointer *rsdp,
+	void *table)
+{
+	int i, entries_num;
+	struct efi_acpi_6_1_root_system_description_table *rsdt;
+	struct efi_acpi_6_1_extended_system_description_table *xsdt = NULL;
+
+	/* The RSDT is mandatory while the XSDT is not */
+	rsdt = (struct efi_acpi_6_1_root_system_description_table *)
+					(uintptr_t)rsdp->rsdt_address;
+
+	if (rsdp->xsdt_address) {
+		xsdt =
+		(struct efi_acpi_6_1_extended_system_description_table *)
+					(uintptr_t)((u32)rsdp->xsdt_address);
+	}
+	/* This should always be MAX_ACPI_TABLES */
+	entries_num = ARRAY_SIZE(rsdt->entry);
+
+	for (i = 0; i < entries_num; i++) {
+		if (rsdt->entry[i] == 0)
+			break;
+	}
+
+	if (i >= entries_num) {
+		debug("ACPI: Error: too many tables\n");
+		return;
+	}
+
+	/* Add table to the RSDT */
+	rsdt->entry[i] = (u32)(uintptr_t)table;
+
+	/* Fix RSDT length or the kernel will assume invalid entries */
+	rsdt->header.length = sizeof(struct efi_acpi_description_header) +
+				(sizeof(u32) * (i + 1));
+
+	/* Re-calculate checksum */
+	rsdt->header.checksum = 0;
+	rsdt->header.checksum =
+		table_compute_checksum((u8 *)rsdt, rsdt->header.length);
+
+	/*
+	 * And now the same thing for the XSDT. We use the same index as for
+	 * now we want the XSDT and RSDT to always be in sync in U-Boot
+	 */
+	if (xsdt) {
+		/* Add table to the XSDT */
+		xsdt->entry[i] = (u64)(u32)(uintptr_t)table;
+
+		/* Fix XSDT length */
+		xsdt->header.length =
+			sizeof(struct efi_acpi_description_header) +
+			(sizeof(u64) * (i + 1));
+
+		/* Re-calculate checksum */
+		xsdt->header.checksum = 0;
+		xsdt->header.checksum =
+			table_compute_checksum((u8 *)xsdt, xsdt->header.length);
+	}
+}
+
+__weak void dynamic_modify_fadt_table(void *table) {}
+__weak void dynamic_modify_gtdt_table(void *table) {}
+__weak void dynamic_modify_madt_table(void *table) {}
+__weak void dynamic_modify_mcfg_table(void *table) {}
+__weak void dynamic_modify_spcr_table(void *table) {}
+__weak void dynamic_modify_iort_table(void *table) {}
+
+ulong write_acpi_tables(ulong start)
+{
+	u32 current;
+	u8 i;
+	ulong dsdt_address = 0xFFFFFFFF;
+	u16 head_size =
+		sizeof(struct efi_acpi_description_header);
+
+	struct efi_acpi_description_header			*p_head;
+	struct efi_acpi_6_1_root_system_description_pointer	*ft_rsdp;
+	struct efi_acpi_6_1_root_system_description_table	*ft_rsdt;
+	struct efi_acpi_6_1_extended_system_description_table	*ft_xsdt;
+	struct efi_acpi_6_1_fixed_acpi_description_table	*ft_fadt;
+
+	current = start;
+
+	debug("ACPI: Writing ACPI tables at %lx\n", start);
+	/* We need at least an RSDP and an RSDT Table */
+	ft_rsdp = (struct efi_acpi_6_1_root_system_description_pointer *)
+							(uintptr_t)current;
+	current +=
+		sizeof(struct efi_acpi_6_1_root_system_description_pointer);
+	ft_rsdt = (struct efi_acpi_6_1_root_system_description_table *)
+							(uintptr_t)current;
+	current +=
+		sizeof(struct efi_acpi_6_1_root_system_description_table);
+	ft_xsdt = (struct efi_acpi_6_1_extended_system_description_table *)
+							(uintptr_t)current;
+	current +=
+		sizeof(struct efi_acpi_6_1_extended_system_description_table);
+
+	/* clear all table memory */
+	memset((void *)start, 0, current - start);
+
+	acpi_write_rsdp(ft_rsdp, ft_rsdt, ft_xsdt);
+	acpi_write_rsdt(ft_rsdt);
+	acpi_write_xsdt(ft_xsdt);
+
+	register_acpi_table_data();
+	if (acpi_table_count) {
+		for (i = 0; i < acpi_table_count; i++) {
+			debug("ACPI:    * table\n");
+			p_head = (struct efi_acpi_description_header *)
+						(uintptr_t)current;
+			memcpy(p_head, array_acpi_table_address[i], head_size);
+			current += sizeof(struct efi_acpi_description_header);
+			memcpy((char *)(uintptr_t)current,
+			       (char *)array_acpi_table_address[i] +
+				sizeof(struct efi_acpi_description_header),
+			       p_head->length -
+				sizeof(struct efi_acpi_description_header));
+			current += p_head->length -
+				sizeof(struct efi_acpi_description_header);
+
+			/* only dsdt not add to rsdp,it is connect to fadt */
+			/* is not dsdt table */
+			if (p_head->signature !=
+				SIGNATURE_32('D', 'S', 'D', 'T')) {
+				acpi_add_table(ft_rsdp, p_head);
+			} else {
+				debug("this is dsdt table\n");
+				dsdt_address = (ulong)(uintptr_t)p_head;
+			}
+
+			/* fadt table need to add dsdt table */
+			/* is fadt table */
+			if (p_head->signature ==
+				SIGNATURE_32('F', 'A', 'C', 'P')) {
+				debug("this is fadt table\n");
+				dynamic_modify_fadt_table(p_head);
+				ft_fadt =
+			(struct efi_acpi_6_1_fixed_acpi_description_table *)
+						p_head;
+				ft_fadt->x_dsdt = (u64)dsdt_address;
+			}
+
+			/* dynamic modify the tables */
+			switch (p_head->signature) {
+				/* gtdt */
+			case SIGNATURE_32('G', 'T', 'D', 'T'):
+				dynamic_modify_gtdt_table(p_head);
+				break;
+			/* mcfg*/
+			case SIGNATURE_32('M', 'C', 'F', 'G'):
+				dynamic_modify_mcfg_table(p_head);
+				break;
+			/* madt*/
+			case SIGNATURE_32('A', 'P', 'I', 'C'):
+				dynamic_modify_madt_table(p_head);
+				break;
+			/* iort*/
+			case SIGNATURE_32('F', 'A', 'C', 'P'):
+				dynamic_modify_iort_table(p_head);
+				break;
+			/* spcr*/
+			case SIGNATURE_32('S', 'P', 'C', 'R'):
+				dynamic_modify_spcr_table(p_head);
+				break;
+			default:
+				break;
+			}
+
+			/* add checksum for table */
+			p_head->checksum = 0;
+			p_head->checksum =
+			table_compute_checksum((void *)p_head, p_head->length);
+		}
+	}
+
+	debug("current = %x\n", current);
+	debug("ACPI: done\n");
+
+	return current;
+}
+
diff --git a/board/phytium/durian/Makefile b/board/phytium/durian/Makefile
index c2fbf19..e673b67 100644
--- a/board/phytium/durian/Makefile
+++ b/board/phytium/durian/Makefile
@@ -7,3 +7,21 @@
 
 obj-y += durian.o
 
+ifdef CONFIG_ARM_ACPI_TABLE
+	        obj-y   +=acpi_table.o
+
+obj-$(CONFIG_DSDT_TABLE)   += acpi_table/dsdt.o
+obj-$(CONFIG_SSDT_TABLE)   += acpi_table/ssdt.o
+
+obj-y   += acpi_table/rsdp.o
+obj-y   += acpi_table/rsdt.o
+obj-y   += acpi_table/xsdt.o
+obj-$(CONFIG_FADT_TABLE)   += acpi_table/fadt.o
+obj-$(CONFIG_MADT_TABLE)   += acpi_table/madt.o
+obj-$(CONFIG_MCFG_TABLE)   += acpi_table/mcfg.o
+obj-$(CONFIG_GTDT_TABLE)   += acpi_table/gtdt.o
+obj-$(CONFIG_IORT_TABLE)   += acpi_table/iort.o
+obj-$(CONFIG_SPCR_TABLE)   += acpi_table/spcr.o
+obj-$(CONFIG_SRAT_TABLE)   += acpi_table/srat.o
+obj-$(CONFIG_SLIT_TABLE)   += acpi_table/slit.o
+endif
diff --git a/board/phytium/durian/acpi_platform.h b/board/phytium/durian/acpi_platform.h
new file mode 100644
index 0000000..bff7fb9
--- /dev/null
+++ b/board/phytium/durian/acpi_platform.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Based on acpi61.h from edk2
+ *
+ * (C) Copyright 2019
+ * Phytium Technology Ltd <www.phytium.com>
+ * Steven Hao <liuhao@phytium.com.cn>
+ */
+
+#ifndef __ARM_PHYT_BOARD_H__
+#define __ARM_PHYT_BOARD_H__
+/*
+ * ACPI table information used to initialize tables.
+ */
+#define EFI_ACPI_ARM_OEM_ID	{ 'A', 'R', 'M', 'L', 'T', 'D' }
+#define EFI_ACPI_ARM_OEM_TABLE_ID	\
+		SIGNATURE_64('A', 'R', 'M', '-', 'P', 'H', 'Y', 'T')
+#define EFI_ACPI_ARM_OEM_REVISION	0x20180509
+#define EFI_ACPI_ARM_CREATOR_ID		SIGNATURE_32('A', 'R', 'M', ' ')
+#define EFI_ACPI_ARM_CREATOR_REVISION	0x00000099
+
+/*
+ * A macro to initialise the common header part of EFI ACPI tables
+ * as defined by EFI_ACPI_DESCRIPTION_HEADER structure.
+ */
+#define arm_acpi_header(signature, type, revision) {              \
+	signature,                      /* u32  signature */       \
+	sizeof(type),                  /* u32  length */          \
+	revision,                       /* u8   revision */        \
+	0,                              /* u8   checksum */        \
+	EFI_ACPI_ARM_OEM_ID,        /* u8   oem_id[6] */        \
+	EFI_ACPI_ARM_OEM_TABLE_ID,      /* u64  oem_table_id */      \
+	EFI_ACPI_ARM_OEM_REVISION,      /* u32  oem_revision */     \
+	EFI_ACPI_ARM_CREATOR_ID,        /* u32  creator_id */       \
+	EFI_ACPI_ARM_CREATOR_REVISION   /* u32  creator_revision */ \
+}
+#endif
+
diff --git a/board/phytium/durian/acpi_table.c b/board/phytium/durian/acpi_table.c
new file mode 100644
index 0000000..5897f87
--- /dev/null
+++ b/board/phytium/durian/acpi_table.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019, PHYTIUM <bmeng.cn@gmail.com>
+ * Steven Hao <liuhao@phytium.com.cn>
+ */
+
+#include <common.h>
+#include <asm/acpi_table.h>
+
+unsigned char *array_acpi_table_address[32];
+unsigned char  acpi_table_count;
+
+/* record the acpi_table data and count */
+void register_acpi_table_data(void)
+{
+	acpi_table_count = 0;
+
+	#ifdef CONFIG_DSDT_TABLE
+		array_acpi_table_address[acpi_table_count] =
+						(unsigned char *)&DsdtAmlCode;
+		acpi_table_count++;
+	#endif
+	#ifdef CONFIG_FADT_TABLE
+		array_acpi_table_address[acpi_table_count] = fadt_data;
+		acpi_table_count++;
+	#endif
+	#ifdef CONFIG_SSDT_TABLE
+		array_acpi_table_address[acpi_table_count] =
+						(unsigned char *)&SsdtAmlCode;
+		acpi_table_count++;
+	#endif
+	#ifdef CONFIG_MADT_TABLE
+		array_acpi_table_address[acpi_table_count] = madt_data;
+		acpi_table_count++;
+	#endif
+	#ifdef CONFIG_GTDT_TABLE
+		array_acpi_table_address[acpi_table_count] = gtdt_data;
+		acpi_table_count++;
+	#endif
+	#ifdef CONFIG_MCFG_TABLE
+		array_acpi_table_address[acpi_table_count] = mcfg_data;
+		acpi_table_count++;
+	#endif
+	#ifdef CONFIG_SPCR_TABLE
+		array_acpi_table_address[acpi_table_count] = spcr_data;
+		acpi_table_count++;
+	#endif
+	#ifdef CONFIG_IORT_TABLE
+		array_acpi_table_address[acpi_table_count] = iort_data;
+		acpi_table_count++;
+	#endif
+}
+
diff --git a/board/phytium/durian/acpi_table/dsdt.asl b/board/phytium/durian/acpi_table/dsdt.asl
new file mode 100644
index 0000000..f789524
--- /dev/null
+++ b/board/phytium/durian/acpi_table/dsdt.asl
@@ -0,0 +1,305 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019
+ * Steven Hao <liuhao@phytium.com.cn>
+ */
+
+DefinitionBlock("dsdt.aml", "DSDT", 2, "U-BOOT", "U-BOOTBL", 0x00010000){
+	Scope(_SB) {
+		Method (_OSC, 4, Serialized)  {
+			CreateDWordField (Arg3, 0x00, STS0)
+				CreateDWordField (Arg3, 0x04, CAP0)
+				If (Arg0 == ToUUID ("0811b06e-4a27-44f9-8d60-3cbbc22e7b48")) {
+					DBGC(2, "_OSC OSPM Arg1:", Arg1)
+					DBGC(2, "CAP0:", CAP0)
+					DBGC(2, "STS0:", STS0)
+					If (!(Arg1 == One)) {
+						STS0 &= ~0x1F
+						STS0 |= 0x0A
+					} Else {
+						If ((CAP0 & 0x100)) {
+							CAP0 &= ~0x100
+							STS0 &= ~0x1F
+							STS0 |= 0x12
+						}
+					}
+				} Else {
+					STS0 &= ~0x1F
+					STS0 |= 0x06
+				}
+			Return (Arg3)
+		}
+
+		Device (CLU0) { 	/* Cluster0 state */
+			Name(_HID, "ACPI0010")
+			Name(_UID, 1)
+
+			Device(CPU0) { 	/*  Cluster 0, Cpu 0 */
+				Name(_HID, "ACPI0007")
+				Name(_UID, 0)
+				Name (_DSD, Package () {
+					ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+					Package () {
+						Package () {"clock-name","c0"},
+						Package () {"clock-domain",0},
+					}
+				})
+			}
+
+			Device(CPU1) { 	/*  Cluster 0, Cpu 1 */
+				Name(_HID, "ACPI0007")
+				Name(_UID, 1)
+				Name (_DSD, Package () {
+					ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+					Package () {
+						Package () {"clock-name","c0"},
+						Package () {"clock-domain",0},
+					}
+				})
+			}
+		}
+
+		Device (CLU1) { 	/* Cluster1 state */
+			Name(_HID, "ACPI0010")
+			Name(_UID, 2)
+
+			Device(CPU2) { 	/*  Cluster 0, Cpu 2 */
+				Name(_HID, "ACPI0007")
+				Name(_UID, 2)
+				Name (_DSD, Package () {
+					ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+					Package () {
+						Package () {"clock-name","c1"},
+						Package () {"clock-domain",1},
+					}
+				})
+			}
+
+			Device(CPU3) { 	/* Cluster 0, Cpu 3 */
+				Name(_HID, "ACPI0007")
+				Name(_UID, 3)
+				Name (_DSD, Package () {
+					ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+					Package () {
+						Package () {"clock-name","c1"},
+						Package () {"clock-domain",1},
+					}
+				})
+			}
+		}
+
+		/* UART 1 */
+		Device(UAR1) {
+			Name(_HID, "ARMH0011")
+			Name(_UID, 1)
+			Name(_CRS, ResourceTemplate() {
+				Memory32Fixed(ReadWrite, 0x28001000, 0x1000)
+				Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) {39}
+			})
+		}
+
+		Device(KBC) {
+			Name(_HID, "KBCI8042")
+			Name(_UID, 0)
+			Name(_CRS, ResourceTemplate() {
+				Memory32Fixed(ReadWrite, 0x20000000, 0x100)
+				Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) {37}
+			})
+		}
+
+		Device (ETH0) {
+			Name (_HID, "FTGM0001")
+			Name (_UID, 0)
+			Name (_CRS, ResourceTemplate () {
+				Memory32Fixed (ReadWrite, 0x2820c000, 0x2000)
+				Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) {81}
+			})
+			Name (_DSD, Package () {
+				ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+				Package () {
+					Package () {"interrupt-names", "macirq"},
+					Package () {"clocks", 3},
+					Package () {"clock-names", "stmmaceth"},
+					Package () {"snps,pbl", 0x10},
+					Package () {"snps,abl", 0x20},
+					Package () {"snps,burst_len", 0x0e},
+					Package () {"snps,multicast-filter-bins", 0x40},
+					Package () {"snps,perfect-filter-entries", 0x41},
+					Package () {"max-frame-size", 0x2328},
+					Package () {"phy-mode", "rgmii"},
+					Package () {"clock-frequency",250000000},
+					Package () {"bus_id",0},
+					Package () {"txc-skew-ps", 0x3e8},
+					Package () {"rxc-skew-ps", 0x3e8},
+				}
+			})
+		}
+
+		Device (ETH1) {
+			Name (_HID, "FTGM0001")
+			Name (_UID, 1)
+			Name (_CRS, ResourceTemplate () {
+				Memory32Fixed (ReadWrite, 0x28210000, 0x2000)
+				Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) {82}
+			})
+			Name (_DSD, Package () {
+				ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+				Package () {
+					Package () {"interrupt-names", "macirq"},
+					Package () {"clocks", 3},
+					Package () {"clock-names", "stmmaceth"},
+					Package () {"snps,pbl", 0x10},
+					Package () {"snps,abl", 0x20},
+					Package () {"snps,burst_len", 0x0e},
+					Package () {"snps,multicast-filter-bins", 0x40},
+					Package () {"snps,perfect-filter-entries", 0x41},
+					Package () {"max-frame-size", 0x2328},
+					Package () {"phy-mode", "rgmii"},
+					Package () {"clock-frequency",250000000},
+					Package () {"bus_id",1},
+					Package () {"txc-skew-ps", 0x3e8},
+					Package () {"rxc-skew-ps", 0x3e8},
+				}
+			})
+		}
+
+		Device(GPI0) {
+			Name(_HID, "FTGP0001")  //FTGPIO01
+			Name(_ADR, 0)
+			Name(_UID, 0)
+			Name (_CRS, ResourceTemplate ()  {
+				Memory32Fixed (ReadWrite, 0x28004000, 0x1000)
+				Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) {42}
+			})
+
+			Device(GP00) {
+				Name(_HID, "FTGP0001") //FTGPIO01
+				Name(_ADR, 0)
+				Name (_DSD, Package () {
+					ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+					Package () {
+						Package () {"reg",0},
+						Package () {"snps,nr-gpios",8},
+					}
+				})
+			}
+
+			Device(GP01) {
+				Name(_HID, "FTGP0001") //FTGPIO01
+				Name(_ADR, 1)
+				Name (_DSD, Package () {
+					ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+					Package () {
+						Package () {"reg",1},
+						Package () {"snps,nr-gpios",8},
+					}
+				})
+			}
+		}
+
+		Device(GPI1) {
+			Name(_HID, "FTGP0001")  //FTGPIO01
+			Name(_ADR, 1)
+			Name(_UID, 1)
+			Name (_CRS, ResourceTemplate ()  {
+				Memory32Fixed (ReadWrite, 0x28005000, 0x1000)
+				Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) {43}
+			})
+
+			Device(GP00) {
+				Name(_HID, "FTGP0001") //FTGPIO01
+				Name(_ADR, 0)
+				Name (_DSD, Package () {
+					ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+					Package () {
+						Package () {"reg",0},
+						Package () {"snps,nr-gpios",8},
+					}
+				})
+			}
+
+			Device(GP01) {
+				Name(_HID, "FTGP0001")
+				Name(_ADR, 1)
+				Name (_DSD, Package () {
+					ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+					Package () {
+						Package () {"reg",1},
+						Package () {"snps,nr-gpios",8},
+					}
+				})
+			}
+		}
+
+		/* SD controller */
+		Device (SDC0) {
+			Name (_HID, "FTSD0001")
+			Name (_UID, 0)
+			Name (_CRS, ResourceTemplate () {
+				Memory32Fixed (ReadWrite, 0x28207C00, 0x100)
+				Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) {52, 53, 54}
+			})
+		}
+
+		/* HDAudio device */
+		Device (HDA0) {
+			Name (_HID, "FTHD0001")
+			Name (_UID, 0)
+			Name (_CRS, ResourceTemplate () {
+				Memory32Fixed (ReadWrite, 0x28206000, 0x1000)
+				Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) {55}
+			})
+		}
+
+		/* RAS */
+		Device (RAS0) {
+			Name (_HID, "FTRA0001")
+			Name (_UID, 0)
+			Name (_CRS, ResourceTemplate () {
+				Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) {32,33}
+			})
+		}
+
+		Method(TCOM, 1, Serialized) {
+			OperationRegion(COM0, SystemMemory, 0x28001000, 0x1000)
+			Field(COM0, DWordAcc, NoLock, Preserve) {
+				DAT8, 8,
+				Offset(5),
+				, 5,
+				TRDY, 1,
+			}
+
+			Add(SizeOf(Arg0), One, Local0)
+				Name(BUF0, Buffer(Local0){})
+				Store(Arg0, BUF0)
+				store(0, Local1)
+				Decrement(Local0)
+				While(LNotEqual(Local1, Local0)){
+					while(LEqual(TRDY, ONE)){}
+					Store(DerefOf(Index(BUF0, Local1)), DAT8)
+						Increment(Local1)
+				}
+		}
+
+		Method(DBGC, 3, Serialized) {
+			Name(CRLF, Buffer(2) {0x0D, 0x0A})
+				TCOM(Arg1)
+				if(LEqual(Arg0, 2)){
+					TCOM(ToHexString(Arg2))
+				}
+			TCOM(CRLF)
+		}
+
+		Device (RTC0) {
+			Name (_HID, "FTRT0001")
+			Name (_UID, Zero)
+			Name (_CRS, ResourceTemplate () {
+				Memory32Fixed (ReadWrite,
+					0x2800d000,         // Address Base
+					0x00001000,         // Address Length
+				)
+				Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, , , ) {36,}
+			})
+		}
+	} /* Scope(_SB) */
+}
diff --git a/board/phytium/durian/acpi_table/fadt.c b/board/phytium/durian/acpi_table/fadt.c
new file mode 100644
index 0000000..cc5f1c2
--- /dev/null
+++ b/board/phytium/durian/acpi_table/fadt.c
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019
+ * Steven Hao <liuhao@phytium.com.cn>
+ */
+
+#include <common.h>
+#include <asm/acpi_table.h>
+#include <asm/acpi_table/acpi61.h>
+#include <asm/acpi_table/spcr_table.h>
+#include <asm/acpi_table/acpi_lib.h>
+#include <asm/acpi_table/arm_platform.h>
+#include <asm/acpi_table/io_remapping_table.h>
+#include "../acpi_platform.h"
+
+#define PHYTIUM_FADT_SIGNATURE	\
+	EFI_ACPI_6_1_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
+
+struct efi_acpi_6_1_fixed_acpi_description_table phy_fadt = {
+	arm_acpi_header
+	(PHYTIUM_FADT_SIGNATURE,
+	struct efi_acpi_6_1_fixed_acpi_description_table,
+	EFI_ACPI_6_1_FIXED_ACPI_DESCRIPTION_TABLE_REVISION
+	),
+	0,
+	0,
+	0x00,
+	EFI_ACPI_6_1_PM_PROFILE_ENTERPRISE_SERVER,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	EFI_ACPI_6_1_HW_REDUCED_ACPI | EFI_ACPI_6_1_LOW_POWER_S0_IDLE_CAPABLE,
+	null_gas,
+	0,
+	EFI_ACPI_6_1_ARM_PSCI_COMPLIANT,
+	EFI_ACPI_6_1_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION,
+	0,
+	0,
+	null_gas,
+	null_gas,
+	null_gas,
+	null_gas,
+	null_gas,
+	null_gas,
+	null_gas,
+	null_gas,
+	null_gas,
+	null_gas,
+	0
+};
+
+unsigned char *fadt_data = (unsigned char *)&phy_fadt;
+
diff --git a/board/phytium/durian/acpi_table/gtdt.c b/board/phytium/durian/acpi_table/gtdt.c
new file mode 100644
index 0000000..294389c
--- /dev/null
+++ b/board/phytium/durian/acpi_table/gtdt.c
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019
+ * Steven Hao <liuhao@phytium.com.cn>
+ */
+
+#include <common.h>
+#include <asm/acpi_table.h>
+#include <asm/acpi_table/acpi61.h>
+#include <asm/acpi_table/arm_platform.h>
+#include "../acpi_platform.h"
+
+#define GTDT_TIMER_EDGE_TRIGGERED   \
+	EFI_ACPI_6_1_GTDT_TIMER_FLAG_TIMER_INTERRUPT_MODE
+#define GTDT_TIMER_LEVEL_TRIGGERED  0
+#define GTDT_TIMER_ACTIVE_LOW       \
+	EFI_ACPI_6_1_GTDT_TIMER_FLAG_TIMER_INTERRUPT_POLARITY
+#define GTDT_TIMER_ACTIVE_HIGH      0
+#define GTDT_TIMER_ALWAYS_ON_CAPABILITY	\
+	EFI_ACPI_6_1_GTDT_TIMER_FLAG_ALWAYS_ON_CAPABILITY
+
+#define GTDT_GTIMER_FLAGS           \
+	(GTDT_TIMER_ACTIVE_LOW | GTDT_TIMER_LEVEL_TRIGGERED)
+
+#define PHYTIUM_GTDT_SIGNATURE	\
+	EFI_ACPI_6_1_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE
+
+#pragma pack(1)
+
+struct efi_acpi_6_1_generic_timer_description_tables {
+	struct efi_acpi_6_1_generic_timer_description_table		gtdt;
+	struct efi_acpi_6_1_gtdt_sbsa_generic_watchdog_structure
+					watchdogs[2];
+};
+
+#pragma pack()
+
+struct efi_acpi_6_1_generic_timer_description_tables phy_gtdt = {
+	{
+		arm_acpi_header
+		(PHYTIUM_GTDT_SIGNATURE,
+		struct efi_acpi_6_1_generic_timer_description_tables,
+		EFI_ACPI_6_1_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION
+		),
+		0xFFFFFFFFFFFFFFFF,	/* physical_address */
+		0,			/* reserved */
+		29,			/* secure_pl1_timer_GSIV */
+		GTDT_GTIMER_FLAGS,	/* secure_pl1_timer_flags */
+		30,			/* non_secure_pl1_timer_GSIV */
+		GTDT_GTIMER_FLAGS,	/* non_secure_pl1_timer_flags */
+		27,			/* virtual_timer_GSIV */
+		GTDT_GTIMER_FLAGS,	/* virtual_timer_flags */
+		26,			/* non_secure_pl2_timer_GSIV */
+		GTDT_GTIMER_FLAGS,	/* non_secure_pl2_timer_flags */
+		0xFFFFFFFFFFFFFFFF,	/* cnt_read_base_physical_address */
+		2,
+		sizeof(struct efi_acpi_6_1_generic_timer_description_table)
+	},
+	{
+		{
+			1,			/* type */
+			28,			/* size of this structure */
+			0,			/* reserved */
+			0x2800a000,	/* refresh_frame physical address */
+			0x2800b000,	/* watchdog_control_frame phy_address */
+			48,			/* watchdog timer GSIV */
+			0,			/* watchdog timer flags high_l*/
+		},
+		{
+			1,
+			28,
+			0,
+			0x28016000,
+			0x28017000,
+			49,
+			0,
+		}
+	}
+};
+
+unsigned char *gtdt_data = (unsigned char *)&phy_gtdt;
diff --git a/board/phytium/durian/acpi_table/iort.c b/board/phytium/durian/acpi_table/iort.c
new file mode 100644
index 0000000..e813bac
--- /dev/null
+++ b/board/phytium/durian/acpi_table/iort.c
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019
+ * Steven Hao <liuhao@phytium.com.cn>
+ */
+
+#include <common.h>
+#include <asm/acpi_table.h>
+#include <asm/acpi_table/acpi61.h>
+#include <asm/acpi_table/arm_platform.h>
+#include <asm/acpi_table/io_remapping_table.h>
+#include "../acpi_platform.h"
+
+#define FIELD_OFFSET(type, name)	__builtin_offsetof(type, name)
+
+#define PHYTIUM_IORT_SIGNATURE	\
+	EFI_ACPI_6_1_IO_REMAPPING_TABLE_SIGNATURE
+
+#pragma pack(1)
+struct phytium_its_node {
+	struct efi_acpi_6_0_io_remapping_its_node        node;
+	u32                                    identifiers[1];
+};
+
+struct phytium_rc_node {
+	struct efi_acpi_6_0_io_remapping_rc_node         node;
+	struct efi_acpi_6_0_io_remapping_id_table        rc_id_mapping;
+};
+
+struct phytium_io_remapping_structure {
+	struct efi_acpi_6_0_io_remapping_table         iort;
+	struct phytium_its_node                        its_node;
+	struct phytium_rc_node                         rc_node[1];
+};
+
+#define __phytium_id_mapping(in, num, out, ref, flags)\
+{	\
+	in,	\
+	num,	\
+	out,	\
+	FIELD_OFFSET(struct phytium_io_remapping_structure, ref),\
+	flags	\
+}
+
+struct phytium_io_remapping_structure phy_iort = {
+	{
+		arm_acpi_header
+		(PHYTIUM_IORT_SIGNATURE,
+		struct phytium_io_remapping_structure,
+		EFI_ACPI_IO_REMAPPING_TABLE_REVISION
+		),
+		2,						/* num_nodes */
+		/* node_offset */
+		sizeof(struct efi_acpi_6_0_io_remapping_table),
+		0						/* reserved */
+	},
+	{
+		/*
+		 * its_node
+		 */
+		{
+			{
+				EFI_ACPI_IORT_TYPE_ITS_GROUP,	/* type */
+				sizeof(struct phytium_its_node),/* length */
+				0x0,	/* revision */
+				0x0,	/* reserved */
+				0x0,	/* num_id_mappings */
+				0x0,	/* id_reference */
+			},
+			1,
+		},
+		{
+			0x0
+		},
+	},
+	{
+		/*
+		 * pci_rc_node
+		 */
+		{
+			{
+				{
+					/* type */
+					EFI_ACPI_IORT_TYPE_ROOT_COMPLEX,
+					/* length */
+					sizeof(struct phytium_rc_node),
+					/* revision */
+					0x0,
+					/* reserved */
+					0x0,
+					/* num_id_mappings */
+					0x1,
+					/* _id_reference */
+			FIELD_OFFSET(struct phytium_rc_node, rc_id_mapping),
+				},
+					/* cache_coherent */
+					EFI_ACPI_IORT_MEM_ACCESS_PROP_CCA,
+					/* allocation_hints */
+					0x0,
+					/* reserved */
+					0x0,
+					/* memory_access_flags */
+					EFI_ACPI_IORT_MEM_ACCESS_FLAGS_CPM,
+					/* ats_attribute */
+				EFI_ACPI_IORT_ROOT_COMPLEX_ATS_UNSUPPORTED,
+					/* pci_segment_number */
+					0x0,
+			},
+			__phytium_id_mapping(0x0, 0xffff, 0x0, its_node, 0),
+		}
+	}
+};
+
+#pragma pack()
+
+unsigned char *iort_data = (unsigned char *)&phy_iort;
+
diff --git a/board/phytium/durian/acpi_table/madt.c b/board/phytium/durian/acpi_table/madt.c
new file mode 100644
index 0000000..b7dd1c7
--- /dev/null
+++ b/board/phytium/durian/acpi_table/madt.c
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019
+ * Steven Hao <liuhao@phytium.com.cn>
+ */
+
+#include <common.h>
+#include <asm/acpi_table.h>
+#include <asm/acpi_table/acpi61.h>
+#include <asm/acpi_table/acpi_lib.h>
+#include <asm/acpi_table/arm_platform.h>
+#include "../acpi_platform.h"
+
+#define platform_get_mpid(cluster_id, core_id)	(((cluster_id) << 8) | \
+		(core_id))
+
+#define PHYTIUM_MADT_SIGNATURE \
+	EFI_ACPI_6_1_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE
+
+/*
+ * Multiple APIC Description Table
+ */
+#pragma pack(1)
+
+struct efi_acpi_6_1_multiple_apic_description_table {
+	struct efi_acpi_6_1_multiple_apic_description_table_header	header;
+	struct efi_acpi_6_1_gic_structure		gic_interfaces[4];
+	struct efi_acpi_6_1_gic_distributor_structure	gic_distributor;
+	struct efi_acpi_6_1_gic_its_structure		gic_its[1];
+};
+
+#pragma pack()
+
+#define efi_gicc_structure(acpi_cpu_uid, mpidr, gicr_base_offset)   \
+	efi_acpi_6_1_gicc_structure_init(0, acpi_cpu_uid, mpidr,\
+			EFI_ACPI_6_1_GIC_ENABLED, 23,                   \
+			0x29c00000, (0x29c00000 + 0x20000), \
+			(0x29c00000 + 0x10000), 25, \
+			(0x29980000 + (gicr_base_offset)), 0)
+
+/*
+ * Multiple APIC Description Table
+ */
+struct efi_acpi_6_1_multiple_apic_description_table phy_madt = {
+	{
+		arm_acpi_header
+		(PHYTIUM_MADT_SIGNATURE,
+		struct efi_acpi_6_1_multiple_apic_description_table,
+		EFI_ACPI_6_1_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION
+		),
+		/*
+		 * MADT specific fields
+		 */
+		0, /* LocalApicAddress */
+		0, /* Flags */
+	},
+	{
+		efi_gicc_structure(0x00, platform_get_mpid(0x00, 0), 0x000000),
+		efi_gicc_structure(0x01, platform_get_mpid(0x00, 1), 0x020000),
+		efi_gicc_structure(0x02, platform_get_mpid(0x01, 0), 0x040000),
+		efi_gicc_structure(0x03, platform_get_mpid(0x01, 1), 0x060000),
+	},
+	efi_acpi_6_1_gic_distributor_init(0, 0x29900000, 0, 0x3),
+	{
+		efi_acpi_6_1_gic_its_init(0, 0x29900000 + 0x20000),
+	}
+};
+
+unsigned char *madt_data = (unsigned char *)&phy_madt;
diff --git a/board/phytium/durian/acpi_table/mcfg.c b/board/phytium/durian/acpi_table/mcfg.c
new file mode 100644
index 0000000..69a0081
--- /dev/null
+++ b/board/phytium/durian/acpi_table/mcfg.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019
+ * Steven Hao <liuhao@phytium.com.cn>
+ */
+
+#include <common.h>
+#include <asm/acpi_table.h>
+#include <asm/acpi_table/acpi61.h>
+#include <asm/acpi_table/arm_platform.h>
+#include "../acpi_platform.h"
+
+#define PHYTIUM_MCFG_SIGNATURE	\
+	EFI_ACPI_6_1_PCI_EXPRESS_MEMORY_MAPPED_ADDR_TABLE_SIGNATURE
+#define PHYTIM_MCFG_STRUCTURE_SIZE	\
+(sizeof(struct efi_acpi_6_1_pci_express_memory_mapped_conf_space_table))
+#define ACPI_6_1_MCFG_VERSION  0x1
+
+#pragma pack(1)
+
+struct efi_acpi_6_1_mcfg_config_structure {
+	u64		ull_base_address;
+	u16		us_seg_group_num;
+	u8		uc_start_bus_num;
+	u8		uc_end_bus_num;
+	u32		reserved2;
+};
+
+struct efi_acpi_6_1_mcfg_table_config {
+	struct efi_acpi_description_header	header;
+	u64		reserved1;
+};
+
+struct efi_acpi_6_1_pci_express_memory_mapped_conf_space_table {
+	struct efi_acpi_6_1_mcfg_table_config		acpi_table_mcfg;
+	struct efi_acpi_6_1_mcfg_config_structure	config_structure[1];
+};
+
+#pragma pack()
+
+struct
+efi_acpi_6_1_pci_express_memory_mapped_conf_space_table phy_mcfg = {
+	{
+		{
+			PHYTIUM_MCFG_SIGNATURE,
+			PHYTIM_MCFG_STRUCTURE_SIZE,
+			ACPI_6_1_MCFG_VERSION,
+			0x00,
+			EFI_ACPI_ARM_OEM_ID,
+			EFI_ACPI_ARM_OEM_TABLE_ID,
+			EFI_ACPI_ARM_OEM_REVISION,
+			EFI_ACPI_ARM_CREATOR_ID,
+			EFI_ACPI_ARM_CREATOR_REVISION
+		},
+		0x0000000000000000,	/* reserved */
+	},
+	{
+		{
+			0x40000000,	/* base address */
+			0,			/* segment group number */
+			0,			/* start bus number */
+			0xff,		/* end bus number */
+			0x00000000,	/* reserved */
+		},
+	}
+};
+
+unsigned char *mcfg_data = (unsigned char *)&phy_mcfg;
diff --git a/board/phytium/durian/acpi_table/rsdp.c b/board/phytium/durian/acpi_table/rsdp.c
new file mode 100644
index 0000000..8b3a4e9
--- /dev/null
+++ b/board/phytium/durian/acpi_table/rsdp.c
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019
+ * Steven Hao <liuhao@phytium.com.cn>
+ */
+
+#include <common.h>
+#include <asm/acpi_table.h>
+#include <asm/acpi_table/acpi61.h>
+#include <asm/acpi_table/arm_platform.h>
+#include "../acpi_platform.h"
+
+struct efi_acpi_6_1_root_system_description_pointer		phy_rsdp = {
+	EFI_ACPI_6_1_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE,
+	0,
+	EFI_ACPI_ARM_OEM_ID,
+	2,
+	0,
+	sizeof(struct efi_acpi_6_1_root_system_description_pointer),
+	0,
+	0,
+	{0, 0, 0}
+};
+
+unsigned char *rsdp_data = (unsigned char *)&phy_rsdp;
diff --git a/board/phytium/durian/acpi_table/rsdt.c b/board/phytium/durian/acpi_table/rsdt.c
new file mode 100644
index 0000000..c5cfd1c
--- /dev/null
+++ b/board/phytium/durian/acpi_table/rsdt.c
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019
+ * Steven Hao <liuhao@phytium.com.cn>
+ */
+
+#include <common.h>
+#include <asm/acpi_table.h>
+#include <asm/acpi_table/acpi61.h>
+#include <asm/acpi_table/arm_platform.h>
+#include "../acpi_platform.h"
+
+#define PHYTIUM_RSDT_SIGNATURE	\
+	EFI_ACPI_6_1_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
+
+struct efi_acpi_6_1_root_system_description_table	phy_rsdt = {
+	arm_acpi_header
+	(PHYTIUM_RSDT_SIGNATURE,
+	struct efi_acpi_6_1_root_system_description_table,
+	EFI_ACPI_6_1_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION
+	),
+	{
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+	}
+};
+
+unsigned char *rsdt_data = (unsigned char *)&phy_rsdt;
diff --git a/board/phytium/durian/acpi_table/spcr.c b/board/phytium/durian/acpi_table/spcr.c
new file mode 100644
index 0000000..1b3ecc7
--- /dev/null
+++ b/board/phytium/durian/acpi_table/spcr.c
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019
+ * Steven Hao <liuhao@phytium.com.cn>
+ */
+
+#include <common.h>
+#include <asm/acpi_table.h>
+#include <asm/acpi_table/acpi61.h>
+#include <asm/acpi_table/acpi_lib.h>
+#include <asm/acpi_table/spcr_table.h>
+#include <asm/acpi_table/arm_platform.h>
+#include "../acpi_platform.h"
+
+/*
+ * References:
+ * Serial Port Console Redirection Table Specification Version 1.03
+ * - August 10, 2015
+ */
+
+#define SPCR_FLOW_CONTROL_NONE           0
+
+#define PHYTIUM_SPCR_SIGNATURE	\
+	EFI_ACPI_6_1_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE
+
+struct efi_acpi_serial_port_console_redirection_table phy_spcr = {
+	arm_acpi_header
+	(PHYTIUM_SPCR_SIGNATURE,
+	struct efi_acpi_serial_port_console_redirection_table,
+	EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION
+	),
+	/* u8		interface_type */
+	EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERFACE_TYPE_16550,
+	/* u8		reserved1[3] */
+	{
+		EFI_ACPI_RESERVED_BYTE,
+		EFI_ACPI_RESERVED_BYTE,
+		EFI_ACPI_RESERVED_BYTE
+	},
+	/* struct efi_acpi_6_0_generic_address_structure base_address */
+	arm_gas32(0x28001000),
+	/* u8		InterruptType */
+	EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERRUPT_TYPE_GIC,
+	/* u8		irq */
+	0,			/* not used on ARM */
+	/* u32		global_system_interrupt */
+	67,
+	/* u8		baud_rate */
+	EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_115200,
+	/* u8		parity */
+	EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_PARITY_NO_PARITY,
+	/* u8		stop_bits */
+	EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_STOP_BITS_1,
+	/* u8		flow_control */
+	SPCR_FLOW_CONTROL_NONE,
+	/* u8		terminal_type */
+	EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_TERMINAL_TYPE_ANSI,
+	/* u8		reserved2 */
+	EFI_ACPI_RESERVED_BYTE,
+	/* u16		pci_device_id */
+	0xFFFF,
+	/* u16		pci_vendor_id */
+	0xFFFF,
+	/* u8		pci_bus_number */
+	0x00,
+	/* u8		pci_device_number */
+	0x00,
+	/* u8		pci_function_number */
+	0x00,
+	/* u32		pci_flags */
+	0x00000000,
+	/* u8		pci_segment */
+	0x00,
+	/* u32		reserved3 */
+	EFI_ACPI_RESERVED_DWORD
+};
+
+unsigned char *spcr_data = (unsigned char *)&phy_spcr;
diff --git a/board/phytium/durian/acpi_table/ssdt.asl b/board/phytium/durian/acpi_table/ssdt.asl
new file mode 100644
index 0000000..218cddd
--- /dev/null
+++ b/board/phytium/durian/acpi_table/ssdt.asl
@@ -0,0 +1,190 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019
+ * Steven Hao <liuhao@phytium.com.cn>
+ */
+
+#define LNK_DEVICE(Unique_Id, Link_Name, irq)\
+	Device(Link_Name) {	\
+		Name(_HID, EISAID("PNP0C0F"))	\
+		Name(_UID, Unique_Id)		\
+		Name(_PRS, ResourceTemplate() {		\
+			Interrupt(ResourceProducer, Level, ActiveHigh, Exclusive) {irq}\
+		})			\
+		Method (_CRS, 0) { Return (_PRS) }	\
+		Method (_SRS, 1) { }		\
+		Method (_DIS) { }		\
+	}
+
+/*
+ * Address: uses the same format as _ADR
+ * Pin: The PCI pin number of the device (0-INTA, 1-INTB, 2-INTC, 3-INTD).
+ * Link: Interrupt allocated via Link device.
+ * Zero: global system interrupt number (no used)
+ */
+
+#define PRT_ENTRY(Address, Pin, Link)	\
+	Package (4) {	\
+		Address,	\
+		Pin,	\
+		Link,	\
+		Zero	\
+	}
+
+#define ROOT_PRT_ENTRY(Dev, Pin, Link)  \
+		 PRT_ENTRY(Dev * 0x10000 + 0xFFFF, Pin, Link)
+
+DefinitionBlock("ssdt.aml", "SSDT", 1, "ARMLTD", "PHYTIUM", 0x20190901){
+	Scope(_SB) {
+		External (\_SB.DBGC, MethodObj)
+			/*
+			 * PCI Root Complex
+			 */
+			LNK_DEVICE(1, LNKA, 60)
+			LNK_DEVICE(2, LNKB, 61)
+			LNK_DEVICE(3, LNKC, 62)
+			LNK_DEVICE(4, LNKD, 63)
+
+			Device(PCI0)
+			{
+				Name(_HID, EISAID("PNP0A08")) /* PCI Express Root Bridge */
+				Name(_CID, EISAID("PNP0A03")) /* Compatible PCI Root Bridge */
+				Name(_SEG, Zero) /* PCI Segment Group number */
+				Name(_BBN, 0)	/* PCI Base Bus Number */
+				Name(_CCA, 1)	/* Initially mark the PCI coherent (for JunoR1) */
+
+				/* Root Complex */
+				Device (RP0) {
+					Name(_ADR, 0x00000000)    /* Dev 0, Func 0 */
+				}
+				/* PCI Routing Table */
+				Name(_PRT, Package() {
+					ROOT_PRT_ENTRY(0, 0, LNKA),   /* INTA */
+					ROOT_PRT_ENTRY(0, 1, LNKB),   /* INTB */
+					ROOT_PRT_ENTRY(0, 2, LNKC),   /* INTC */
+					ROOT_PRT_ENTRY(0, 3, LNKD),   /* INTD */
+
+					ROOT_PRT_ENTRY(1, 0, LNKA),   /* INTA */
+					ROOT_PRT_ENTRY(1, 1, LNKB),   /* INTB */
+					ROOT_PRT_ENTRY(1, 2, LNKC),   /* INTC */
+					ROOT_PRT_ENTRY(1, 3, LNKD),   /* INTD */
+
+					ROOT_PRT_ENTRY(2, 0, LNKA),   /* INTA */
+					ROOT_PRT_ENTRY(2, 1, LNKB),   /* INTB */
+					ROOT_PRT_ENTRY(2, 2, LNKC),   /* INTC */
+					ROOT_PRT_ENTRY(2, 3, LNKD),   /* INTD */
+
+					ROOT_PRT_ENTRY(3, 0, LNKA),   /* INTA */
+					ROOT_PRT_ENTRY(3, 1, LNKB),   /* INTB */
+					ROOT_PRT_ENTRY(3, 2, LNKC),   /* INTC */
+					ROOT_PRT_ENTRY(3, 3, LNKD),   /* INTD */
+
+					ROOT_PRT_ENTRY(4, 0, LNKA),   /* INTA */
+					ROOT_PRT_ENTRY(4, 1, LNKB),   /* INTB */
+					ROOT_PRT_ENTRY(4, 2, LNKC),   /* INTC */
+					ROOT_PRT_ENTRY(4, 3, LNKD),   /* INTD */
+
+					ROOT_PRT_ENTRY(5, 0, LNKA),   /* INTA */
+					ROOT_PRT_ENTRY(5, 1, LNKB),   /* INTB */
+					ROOT_PRT_ENTRY(5, 2, LNKC),   /* INTC */
+					ROOT_PRT_ENTRY(5, 3, LNKD),   /* INTD */
+				})
+
+				/* Root complex resources */
+				Method (_CRS, 0, Serialized) {
+					Name (RBUF, ResourceTemplate () {
+						WordBusNumber ( /* Bus numbers assigned to this root */
+							ResourceProducer,
+							MinFixed, MaxFixed, PosDecode,
+							0,   /* AddressGranularity */
+							0,   /* AddressMinimum - Minimum Bus Number */
+							255, /* AddressMaximum - Maximum Bus Number */
+							0,   /* AddressTranslation - Set to 0 */
+							256  /* RangeLength - Number of Busses */
+						)
+
+						DWordMemory ( /* 32-bit BAR Windows */
+							ResourceProducer, PosDecode,
+							MinFixed, MaxFixed,
+							Cacheable, ReadWrite,
+							0x00000000,		/* Granularity */
+							0x58000000,		/* Min Base Address */
+							0x7FFFFFFF,		/* Max Base Address */
+							0x00000000,		/* Translate */
+							0x28000000		/* Length */
+						)
+
+						QWordMemory ( 	/* 64-bit BAR Windows */
+							ResourceProducer, PosDecode,
+							MinFixed, MaxFixed,
+							Cacheable, ReadWrite,
+							0x00000000,		/* Granularity */
+							0x1000000000,		/* Min Base Address */
+							0x1FFFFFFFFF,		/* Max Base Address */
+							0x0000000000,		/* Translate */
+							0x1000000000		/* Length */
+						)
+
+						DWordIo ( // IO window
+							ResourceProducer,
+							MinFixed,
+							MaxFixed,
+							PosDecode,
+							EntireRange,
+							0x00000000,		/* Granularity */
+							0x00000000,		/* Min Base Address */
+							0x00efffff,		/* Max Base Address */
+							0x50000000,		/* Translate */
+							0x00f00000,		/* Length */
+							,,,TypeTranslation
+						)
+					}) /* Name(RBUF) */
+
+					Return (RBUF)
+				} /* Method(_CRS) */
+
+				/*
+				 * OS Control Handoff
+				 */
+				Name(SUPP, Zero) /* PCI _OSC Support Field value */
+					Name(CTRL, Zero) /* PCI _OSC Control Field value */
+
+					Method(_OSC,4) {
+						/* Check for proper UUID */
+						If (LEqual(Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
+							CreateDWordField(Arg3,0,CDW1)
+							CreateDWordField(Arg3,4,CDW2)
+							CreateDWordField(Arg3,8,CDW3)
+
+							/* Save Capabilities DWord2 & 3 */
+							Store(CDW2,SUPP)
+							Store(CDW3,CTRL)
+
+							If (LNotEqual(And(SUPP, 0x16), 0x16)) {
+								And(CTRL,0x1E,CTRL) /* Mask bit 0 (and undefined bits) */
+							}
+
+							/*
+							 * Do not allow native PME, AER (no dependencies)
+							 * Never allow SHPC (no SHPC controller in this system)
+							 */
+							And(CTRL,0x10,CTRL)
+
+							If (LNotEqual(Arg1,One)) {  /* Unknown revision */
+								Or(CDW1,0x08,CDW1)
+							}
+
+							If (LNotEqual(CDW3,CTRL)) {  /* Capabilities bits were masked */
+								Or(CDW1,0x10,CDW1)
+							}
+							/* Update DWORD3 in the buffer */
+							Store(CTRL,CDW3)
+							Return(Arg3)
+						} Else {
+							Or(CDW1,4,CDW1)	/* Unrecognized UUID */
+							Return(Arg3)
+						}
+				} /* End _OSC */
+			} /* PCI0 */
+	}
+}
diff --git a/board/phytium/durian/acpi_table/xsdt.c b/board/phytium/durian/acpi_table/xsdt.c
new file mode 100644
index 0000000..25959d6
--- /dev/null
+++ b/board/phytium/durian/acpi_table/xsdt.c
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019
+ * Steven Hao <liuhao@phytium.com.cn>
+ */
+
+#include <common.h>
+#include <asm/acpi_table.h>
+#include <asm/acpi_table/acpi61.h>
+#include <asm/acpi_table/arm_platform.h>
+#include "../acpi_platform.h"
+
+#define PHYTIUM_XSDT_SIGNATURE	\
+	EFI_ACPI_6_1_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
+
+/*
+ * XSDT table
+ */
+struct efi_acpi_6_1_extended_system_description_table phy_xsdt = {
+	arm_acpi_header
+	(PHYTIUM_XSDT_SIGNATURE,
+	struct efi_acpi_6_1_extended_system_description_table,
+	EFI_ACPI_6_1_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION
+	),
+	{
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+	}
+};
+
+unsigned char *xsdt_data = (unsigned char *)&phy_xsdt;
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index f613cce..d2e15db 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -73,7 +73,8 @@ out:
 							efi_root, NULL));
 }
 
-#if !CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE)
+#if (!CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE) && \
+		!CONFIG_IS_ENABLED(ARM_ACPI_TABLE))
 
 /**
  * copy_fdt() - Copy the device tree to a new location available to EFI
@@ -214,7 +215,8 @@ static efi_status_t efi_install_fdt(const char *fdt_opt)
 	 * The EBBR spec requires that we have either an FDT or an ACPI table
 	 * but not both.
 	 */
-#if CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE)
+#if (CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE) || \
+		CONFIG_IS_ENABLED(ARM_ACPI_TABLE))
 	if (fdt_opt) {
 		printf("ERROR: can't have ACPI table and device tree.\n");
 		return EFI_LOAD_ERROR;
diff --git a/configs/durian_defconfig b/configs/durian_defconfig
index 20177e4..1164a85 100644
--- a/configs/durian_defconfig
+++ b/configs/durian_defconfig
@@ -1,5 +1,14 @@
 CONFIG_ARM=y
 CONFIG_ARM_SMCCC=y
+CONFIG_ARM_ACPI_TABLE=y
+CONFIG_DSDT_TABLE=y
+CONFIG_SSDT_TABLE=y
+CONFIG_FADT_TABLE=y
+CONFIG_GTDT_TABLE=y
+CONFIG_MADT_TABLE=y
+CONFIG_MCFG_TABLE=y
+CONFIG_IORT_TABLE=y
+CONFIG_SPCR_TABLE=y
 CONFIG_TARGET_DURIAN=y
 CONFIG_SYS_TEXT_BASE=0x500000
 CONFIG_NR_DRAM_BANKS=1
diff --git a/include/configs/durian.h b/include/configs/durian.h
index c42a98b..41347ac 100644
--- a/include/configs/durian.h
+++ b/include/configs/durian.h
@@ -36,9 +36,11 @@
 #define CONFIG_SYS_BOOTM_LEN	(60 * 1024 * 1024)
 
 #define CONFIG_EXTRA_ENV_SETTINGS	\
-	"load_kernel=ext4load scsi 0:1 0x90100000 uImage-2004\0"	\
-	"load_fdt=ext4load scsi 0:1 0x95000000 ft2004-pci-64.dtb\0"\
+	"load_kernel=ext4load scsi 0:1 0x90100000 uImage-durian\0"	\
+	"load_fdt=ext4load scsi 0:1 0x95000000 phytium-durian.dtb\0"\
 	"boot_fdt=bootm 0x90100000 -:- 0x95000000\0"	\
-	"distro_bootcmd=run load_kernel; run load_fdt; run boot_fdt"
+	"distro_bootcmd=run load_kernel; run load_fdt; run boot_fdt\0"\
+	"load_acpi_kernel=ext4load scsi 0:1 0x90100000 Image-durian\0"\
+	"acpi_boot=bootefi 0x90100000\0"
 
 #endif
diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
index 7db4060..fc91a55 100644
--- a/lib/efi_loader/Makefile
+++ b/lib/efi_loader/Makefile
@@ -42,3 +42,4 @@ obj-$(CONFIG_PARTITIONS) += efi_disk.o
 obj-$(CONFIG_NET) += efi_net.o
 obj-$(CONFIG_GENERATE_ACPI_TABLE) += efi_acpi.o
 obj-$(CONFIG_GENERATE_SMBIOS_TABLE) += efi_smbios.o
+obj-$(CONFIG_ARM_ACPI_TABLE) += efi_acpi.o
diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c
index de7b616..1971f8f 100644
--- a/lib/efi_loader/efi_setup.c
+++ b/lib/efi_loader/efi_setup.c
@@ -160,7 +160,7 @@ efi_status_t efi_init_obj_list(void)
 	if (ret != EFI_SUCCESS)
 		goto out;
 #endif
-#ifdef CONFIG_GENERATE_ACPI_TABLE
+#if defined(CONFIG_GENERATE_ACPI_TABLE) || defined(CONFIG_ARM_ACPI_TABLE)
 	ret = efi_acpi_register();
 	if (ret != EFI_SUCCESS)
 		goto out;
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index ef116e0..34ffec9 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -416,6 +416,14 @@ $(obj)/dsdt.c:    $(src)/dsdt.asl
 	$(call cmd,acpi_c_asl)
 	$(Q)sed -i -e "s,dsdt_aml_code,AmlCode," $@
 
+$(obj)/acpi_table/dsdt.c:    $(src)/acpi_table/dsdt.asl
+	$(call cmd,acpi_c_asl)
+	$(Q)sed -i -e "s,dsdt_aml_code,DsdtAmlCode," $@
+
+$(obj)/acpi_table/ssdt.c:    $(src)/acpi_table/ssdt.asl
+	$(call cmd,acpi_c_asl)
+	$(Q)sed -i -e "s,ssdt_aml_code,SsdtAmlCode," $@
+
 # Bzip2
 # ---------------------------------------------------------------------------
 
