Merge tag 'efi-2020-07-rc1' of https://gitlab.denx.de/u-boot/custodians/u-boot-efi

Pull request for UEFI sub-system for efi-2020-07-rc1

This pull request

* provides an implementation of UEFI secure booting
* fixes a problem with the rsa_mod_exp driver which stops some boards
  from booting when CONFIG_RSA is enabled which is needed for UEFI
  secure booting
* enables the EFI_RNG_PROTOCOL if DM_RNG is enabled
* fixes some function comments
diff --git a/MAINTAINERS b/MAINTAINERS
index d8d420f..7ac7e21 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -654,9 +654,9 @@
 M:	Simon Glass <sjg@chromium.org>
 S:	Maintained
 T:	git https://gitlab.denx.de/u-boot/u-boot.git
-F:	common/log.c
+F:	common/log*
 F:	cmd/log.c
-F:	test/log/log_test.c
+F:	test/log/
 F:	test/py/tests/test_log.py
 
 MALI DISPLAY PROCESSORS
diff --git a/arch/Kconfig b/arch/Kconfig
index ae9c93e..91e049b 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -96,6 +96,7 @@
 	select DM_SPI_FLASH
 	select HAVE_BLOCK_DEVICE
 	select LZO
+	select OF_BOARD_SETUP
 	select PCI_ENDPOINT
 	select SPI
 	select SUPPORT_OF_CONTROL
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index bbb1e27..dd41090 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1586,6 +1586,7 @@
 config ARCH_STM32MP
 	bool "Support STMicroelectronics STM32MP Socs with cortex A"
 	select ARCH_MISC_INIT
+	select ARCH_SUPPORT_TFABOOT
 	select BOARD_LATE_INIT
 	select CLK
 	select DM
diff --git a/arch/arm/dts/stm32mp157a-avenger96.dts b/arch/arm/dts/stm32mp157a-avenger96.dts
index f577d79..11e7e63 100644
--- a/arch/arm/dts/stm32mp157a-avenger96.dts
+++ b/arch/arm/dts/stm32mp157a-avenger96.dts
@@ -38,21 +38,21 @@
 	led {
 		compatible = "gpio-leds";
 		led1 {
-			label = "green:user1";
+			label = "green:user0";
 			gpios = <&gpioz 7 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
 			default-state = "off";
 		};
 
 		led2 {
-			label = "green:user2";
+			label = "green:user1";
 			gpios = <&gpiof 3 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "mmc0";
 			default-state = "off";
 		};
 
 		led3 {
-			label = "green:user3";
+			label = "green:user2";
 			gpios = <&gpiog 0 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "mmc1";
 			default-state = "off";
diff --git a/arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi b/arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi
index 62c45de..b57f3d5 100644
--- a/arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi
+++ b/arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi
@@ -37,6 +37,12 @@
 			default-state = "on";
 		};
 	};
+
+	/* This is actually on FMC2, but we do not have bus driver for that */
+	ksz8851: ks8851mll@64000000 {
+		compatible = "micrel,ks8851-mll";
+		reg = <0x64000000 0x20000>;
+	};
 };
 
 &i2c4 {
@@ -50,6 +56,68 @@
 	};
 };
 
+&pinctrl {
+	/* These should bound to FMC2 bus driver, but we do not have one */
+	pinctrl-0 = <&fmc_pins_b>;
+	pinctrl-1 = <&fmc_sleep_pins_b>;
+	pinctrl-names = "default", "sleep";
+
+	fmc_pins_b: fmc-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('D', 4, AF12)>, /* FMC_NOE */
+				 <STM32_PINMUX('D', 5, AF12)>, /* FMC_NWE */
+				 <STM32_PINMUX('B', 7, AF12)>, /* FMC_NL */
+				 <STM32_PINMUX('D', 14, AF12)>, /* FMC_D0 */
+				 <STM32_PINMUX('D', 15, AF12)>, /* FMC_D1 */
+				 <STM32_PINMUX('D', 0, AF12)>, /* FMC_D2 */
+				 <STM32_PINMUX('D', 1, AF12)>, /* FMC_D3 */
+				 <STM32_PINMUX('E', 7, AF12)>, /* FMC_D4 */
+				 <STM32_PINMUX('E', 8, AF12)>, /* FMC_D5 */
+				 <STM32_PINMUX('E', 9, AF12)>, /* FMC_D6 */
+				 <STM32_PINMUX('E', 10, AF12)>, /* FMC_D7 */
+				 <STM32_PINMUX('E', 11, AF12)>, /* FMC_D8 */
+				 <STM32_PINMUX('E', 12, AF12)>, /* FMC_D9 */
+				 <STM32_PINMUX('E', 13, AF12)>, /* FMC_D10 */
+				 <STM32_PINMUX('E', 14, AF12)>, /* FMC_D11 */
+				 <STM32_PINMUX('E', 15, AF12)>, /* FMC_D12 */
+				 <STM32_PINMUX('D', 8, AF12)>, /* FMC_D13 */
+				 <STM32_PINMUX('D', 9, AF12)>, /* FMC_D14 */
+				 <STM32_PINMUX('D', 10, AF12)>, /* FMC_D15 */
+				 <STM32_PINMUX('G', 9, AF12)>, /* FMC_NE2_FMC_NCE */
+				 <STM32_PINMUX('G', 12, AF12)>; /* FMC_NE4 */
+			bias-disable;
+			drive-push-pull;
+			slew-rate = <3>;
+		};
+	};
+
+	fmc_sleep_pins_b: fmc-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('D', 4, ANALOG)>, /* FMC_NOE */
+				 <STM32_PINMUX('D', 5, ANALOG)>, /* FMC_NWE */
+				 <STM32_PINMUX('B', 7, ANALOG)>, /* FMC_NL */
+				 <STM32_PINMUX('D', 14, ANALOG)>, /* FMC_D0 */
+				 <STM32_PINMUX('D', 15, ANALOG)>, /* FMC_D1 */
+				 <STM32_PINMUX('D', 0, ANALOG)>, /* FMC_D2 */
+				 <STM32_PINMUX('D', 1, ANALOG)>, /* FMC_D3 */
+				 <STM32_PINMUX('E', 7, ANALOG)>, /* FMC_D4 */
+				 <STM32_PINMUX('E', 8, ANALOG)>, /* FMC_D5 */
+				 <STM32_PINMUX('E', 9, ANALOG)>, /* FMC_D6 */
+				 <STM32_PINMUX('E', 10, ANALOG)>, /* FMC_D7 */
+				 <STM32_PINMUX('E', 11, ANALOG)>, /* FMC_D8 */
+				 <STM32_PINMUX('E', 12, ANALOG)>, /* FMC_D9 */
+				 <STM32_PINMUX('E', 13, ANALOG)>, /* FMC_D10 */
+				 <STM32_PINMUX('E', 14, ANALOG)>, /* FMC_D11 */
+				 <STM32_PINMUX('E', 15, ANALOG)>, /* FMC_D12 */
+				 <STM32_PINMUX('D', 8, ANALOG)>, /* FMC_D13 */
+				 <STM32_PINMUX('D', 9, ANALOG)>, /* FMC_D14 */
+				 <STM32_PINMUX('D', 10, ANALOG)>, /* FMC_D15 */
+				 <STM32_PINMUX('G', 9, ANALOG)>, /* FMC_NE2_FMC_NCE */
+				 <STM32_PINMUX('G', 12, ANALOG)>; /* FMC_NE4 */
+		};
+	};
+};
+
 &pmic {
 	u-boot,dm-pre-reloc;
 };
diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig
index 9615369..7b86ce1 100644
--- a/arch/arm/mach-stm32mp/Kconfig
+++ b/arch/arm/mach-stm32mp/Kconfig
@@ -35,9 +35,10 @@
 
 config STM32MP15x
 	bool "Support STMicroelectronics STM32MP15x Soc"
-	select ARCH_SUPPORT_PSCI if !STM32MP1_TRUSTED
+	select ARCH_SUPPORT_PSCI if !TFABOOT
+	select ARM_SMCCC if TFABOOT
 	select CPU_V7A
-	select CPU_V7_HAS_NONSEC if !STM32MP1_TRUSTED
+	select CPU_V7_HAS_NONSEC if !TFABOOT
 	select CPU_V7_HAS_VIRT
 	select OF_BOARD_SETUP
 	select PINCTRL_STM32
@@ -45,8 +46,8 @@
 	select STM32_RESET
 	select STM32_SERIAL
 	select SYS_ARCH_TIMER
-	imply SYSRESET_PSCI if STM32MP1_TRUSTED
-	imply SYSRESET_SYSCON if !STM32MP1_TRUSTED
+	imply SYSRESET_PSCI if TFABOOT
+	imply SYSRESET_SYSCON if !TFABOOT
 	help
 		support of STMicroelectronics SOC STM32MP15x family
 		STM32MP157, STM32MP153 or STM32MP151
@@ -83,19 +84,9 @@
 
 endchoice
 
-config STM32MP1_TRUSTED
-	bool "Support trusted boot with TF-A"
-	default y if !SPL
-	select ARM_SMCCC
-	help
-		Say Y here to enable boot with TF-A
-		Trusted boot chain is :
-		BootRom => TF-A.stm32 (clock & DDR) => U-Boot.stm32
-		TF-A monitor provides proprietary SMC to manage secure devices
-
 config STM32MP1_OPTEE
 	bool "Support trusted boot with TF-A and OP-TEE"
-	depends on STM32MP1_TRUSTED
+	depends on TFABOOT
 	default n
 	help
 		Say Y here to enable boot with TF-A and OP-TEE
diff --git a/arch/arm/mach-stm32mp/bsec.c b/arch/arm/mach-stm32mp/bsec.c
index 3b923f0..0d5850b 100644
--- a/arch/arm/mach-stm32mp/bsec.c
+++ b/arch/arm/mach-stm32mp/bsec.c
@@ -68,7 +68,7 @@
 	return !!(readl(address + bank) & bit);
 }
 
-#ifndef CONFIG_STM32MP1_TRUSTED
+#ifndef CONFIG_TFABOOT
 /**
  * bsec_check_error() - Check status of one otp
  * @base: base address of bsec IP
@@ -273,7 +273,7 @@
 
 	return ret;
 }
-#endif /* CONFIG_STM32MP1_TRUSTED */
+#endif /* CONFIG_TFABOOT */
 
 /* BSEC MISC driver *******************************************************/
 struct stm32mp_bsec_platdata {
@@ -282,7 +282,7 @@
 
 static int stm32mp_bsec_read_otp(struct udevice *dev, u32 *val, u32 otp)
 {
-#ifdef CONFIG_STM32MP1_TRUSTED
+#ifdef CONFIG_TFABOOT
 	return stm32_smc(STM32_SMC_BSEC,
 			 STM32_SMC_READ_OTP,
 			 otp, 0, val);
@@ -313,7 +313,7 @@
 
 static int stm32mp_bsec_read_shadow(struct udevice *dev, u32 *val, u32 otp)
 {
-#ifdef CONFIG_STM32MP1_TRUSTED
+#ifdef CONFIG_TFABOOT
 	return stm32_smc(STM32_SMC_BSEC,
 			 STM32_SMC_READ_SHADOW,
 			 otp, 0, val);
@@ -336,7 +336,7 @@
 
 static int stm32mp_bsec_write_otp(struct udevice *dev, u32 val, u32 otp)
 {
-#ifdef CONFIG_STM32MP1_TRUSTED
+#ifdef CONFIG_TFABOOT
 	return stm32_smc_exec(STM32_SMC_BSEC,
 			      STM32_SMC_PROG_OTP,
 			      otp, val);
@@ -349,7 +349,7 @@
 
 static int stm32mp_bsec_write_shadow(struct udevice *dev, u32 val, u32 otp)
 {
-#ifdef CONFIG_STM32MP1_TRUSTED
+#ifdef CONFIG_TFABOOT
 	return stm32_smc_exec(STM32_SMC_BSEC,
 			      STM32_SMC_WRITE_SHADOW,
 			      otp, val);
@@ -362,7 +362,7 @@
 
 static int stm32mp_bsec_write_lock(struct udevice *dev, u32 val, u32 otp)
 {
-#ifdef CONFIG_STM32MP1_TRUSTED
+#ifdef CONFIG_TFABOOT
 	if (val == 1)
 		return stm32_smc_exec(STM32_SMC_BSEC,
 				      STM32_SMC_WRLOCK_OTP,
@@ -473,7 +473,7 @@
 	return 0;
 }
 
-#ifndef CONFIG_STM32MP1_TRUSTED
+#ifndef CONFIG_TFABOOT
 static int stm32mp_bsec_probe(struct udevice *dev)
 {
 	int otp;
@@ -500,7 +500,7 @@
 	.ofdata_to_platdata = stm32mp_bsec_ofdata_to_platdata,
 	.platdata_auto_alloc_size = sizeof(struct stm32mp_bsec_platdata),
 	.ops = &stm32mp_bsec_ops,
-#ifndef CONFIG_STM32MP1_TRUSTED
+#ifndef CONFIG_TFABOOT
 	.probe = stm32mp_bsec_probe,
 #endif
 };
diff --git a/arch/arm/mach-stm32mp/cpu.c b/arch/arm/mach-stm32mp/cpu.c
index 9aa5794..74d03fa 100644
--- a/arch/arm/mach-stm32mp/cpu.c
+++ b/arch/arm/mach-stm32mp/cpu.c
@@ -76,7 +76,7 @@
 #define PKG_MASK	GENMASK(2, 0)
 
 #if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
-#ifndef CONFIG_STM32MP1_TRUSTED
+#ifndef CONFIG_TFABOOT
 static void security_init(void)
 {
 	/* Disable the backup domain write protection */
@@ -136,7 +136,7 @@
 	writel(BIT(0), RCC_MP_AHB5ENSETR);
 	writel(0x0, GPIOZ_SECCFGR);
 }
-#endif /* CONFIG_STM32MP1_TRUSTED */
+#endif /* CONFIG_TFABOOT */
 
 /*
  * Debug init
@@ -150,7 +150,7 @@
 }
 #endif /* !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) */
 
-#if !defined(CONFIG_STM32MP1_TRUSTED) && \
+#if !defined(CONFIG_TFABOOT) && \
 	(!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD))
 /* get bootmode from ROM code boot context: saved in TAMP register */
 static void update_bootmode(void)
@@ -198,7 +198,7 @@
 
 #if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
 	dbgmcu_init();
-#ifndef CONFIG_STM32MP1_TRUSTED
+#ifndef CONFIG_TFABOOT
 	security_init();
 	update_bootmode();
 #endif
@@ -214,7 +214,7 @@
 	if ((boot_mode & TAMP_BOOT_DEVICE_MASK) == BOOT_SERIAL_UART)
 		gd->flags |= GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE;
 #if defined(CONFIG_DEBUG_UART) && \
-	!defined(CONFIG_STM32MP1_TRUSTED) && \
+	!defined(CONFIG_TFABOOT) && \
 	(!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD))
 	else
 		debug_uart_init();
diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h b/arch/arm/mach-stm32mp/include/mach/stm32.h
index 6daf9f7..76d593d 100644
--- a/arch/arm/mach-stm32mp/include/mach/stm32.h
+++ b/arch/arm/mach-stm32mp/include/mach/stm32.h
@@ -13,6 +13,7 @@
 #define STM32_RCC_BASE			0x50000000
 #define STM32_PWR_BASE			0x50001000
 #define STM32_DBGMCU_BASE		0x50081000
+#define STM32_FMC2_BASE			0x58002000
 #define STM32_TZC_BASE			0x5C006000
 #define STM32_ETZPC_BASE		0x5C007000
 #define STM32_STGEN_BASE		0x5C008000
diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c
index f7c73e3..e7ec892 100644
--- a/arch/sandbox/cpu/os.c
+++ b/arch/sandbox/cpu/os.c
@@ -8,6 +8,7 @@
 #include <fcntl.h>
 #include <getopt.h>
 #include <setjmp.h>
+#include <signal.h>
 #include <stdio.h>
 #include <stdint.h>
 #include <stdlib.h>
@@ -175,6 +176,13 @@
 	}
 }
 
+static void os_sigint_handler(int sig)
+{
+	os_fd_restore();
+	signal(SIGINT, SIG_DFL);
+	raise(SIGINT);
+}
+
 /* Put tty into raw mode so <tab> and <ctrl+c> work */
 void os_tty_raw(int fd, bool allow_sigs)
 {
@@ -205,6 +213,7 @@
 
 	term_setup = true;
 	atexit(os_fd_restore);
+	signal(SIGINT, os_sigint_handler);
 }
 
 void *os_malloc(size_t length)
diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts
index 4dd82f6..20f6893 100644
--- a/arch/sandbox/dts/sandbox.dts
+++ b/arch/sandbox/dts/sandbox.dts
@@ -10,7 +10,7 @@
 
 	aliases {
 		i2c0 = &i2c_0;
-		pci0 = &pci;
+		pci0 = &pcic;
 		rtc0 = &rtc_0;
 		axi0 = &axi;
 		spi0 = &spi;
@@ -20,6 +20,25 @@
 		reg = <0 CONFIG_SYS_SDRAM_SIZE>;
 	};
 
+	reserved-memory {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		reservation_test0 {
+			size = <0x4000>;
+			alignment = <0x2000>;
+		};
+
+		reservation_test1: restest@a000 {
+			reg = <0x00d0a000 0x2000>;
+		};
+
+		reservation_test2: restest@7000 {
+			reg = <0x00d07000 0x1000>;
+		};
+	};
+
 	cros_ec: cros-ec {
 		reg = <0 0>;
 		u-boot,dm-pre-reloc;
@@ -52,9 +71,10 @@
 		pinctrl-0 = <&pinctrl_i2c0>;
 	};
 
-	pci: pci-controller {
+	pcic: pci@0 {
 		compatible = "sandbox,pci";
 		device_type = "pci";
+		bus-range = <0x00 0xff>;
 		#address-cells = <3>;
 		#size-cells = <2>;
 		ranges = <0x02000000 0 0x10000000 0x10000000 0 0x2000
diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi
index 7cd56c1..e1f68cd 100644
--- a/arch/sandbox/dts/sandbox.dtsi
+++ b/arch/sandbox/dts/sandbox.dtsi
@@ -100,7 +100,7 @@
 		};
 	};
 
-	pci-controller {
+	pci@0 {
 		pci@1e,0 {
 			compatible = "sandbox,pmc";
 			reg = <0xf000 0 0 0 0>;
diff --git a/arch/sandbox/dts/sandbox64.dts b/arch/sandbox/dts/sandbox64.dts
index 5c95cee..a39f94f 100644
--- a/arch/sandbox/dts/sandbox64.dts
+++ b/arch/sandbox/dts/sandbox64.dts
@@ -10,7 +10,7 @@
 
 	aliases {
 		i2c0 = &i2c_0;
-		pci0 = &pci;
+		pci0 = &pcic;
 		rtc0 = &rtc_0;
 		axi0 = &axi;
 		spi0 = &spi;
@@ -20,6 +20,26 @@
 		reg = /bits/ 64 <0 CONFIG_SYS_SDRAM_SIZE>;
 	};
 
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		reservation_test_size {
+			size = <0 0x4000>;
+			alignment = <0 0x2000>;
+		};
+
+		reservation_test@a000 {
+			reg = <0 0x00d0a000 0 0x2000>;
+		};
+
+		reservation_test@7000 {
+			reg = <0 0x00d07000 0 0x1000>;
+		};
+	};
+
+	/* ... */
 	cros_ec: cros-ec {
 		reg = <0 0 0 0>;
 		u-boot,dm-pre-reloc;
@@ -47,9 +67,10 @@
 		pinctrl-0 = <&pinctrl_i2c0>;
 	};
 
-	pci: pci-controller {
+	pcic: pci@0 {
 		compatible = "sandbox,pci";
 		device_type = "pci";
+		bus-range = <0x00 0xff>;
 		#address-cells = <3>;
 		#size-cells = <2>;
 		ranges = <0x02000000 0 0x10000000 0 0x10000000 0 0x2000
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 4a27793..6803c00 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -93,6 +93,8 @@
 			<&gpio_b 9 0xc 3 2 1>;
 		int-value = <1234>;
 		uint-value = <(-1234)>;
+		int64-value = /bits/ 64 <0x1111222233334444>;
+		int-array = <5678 9123 4567>;
 		interrupts-extended = <&irq 3 0>;
 	};
 
@@ -206,6 +208,10 @@
 		compatible = "denx,u-boot-devres-test";
 	};
 
+	acpi-test {
+		compatible = "denx,u-boot-acpi-test";
+	};
+
 	clocks {
 		clk_fixed: clk-fixed {
 			compatible = "fixed-clock";
@@ -463,9 +469,10 @@
 		compatible = "sandbox,pch";
 	};
 
-	pci0: pci-controller0 {
+	pci0: pci@0 {
 		compatible = "sandbox,pci";
 		device_type = "pci";
+		bus-range = <0x00 0xff>;
 		#address-cells = <3>;
 		#size-cells = <2>;
 		ranges = <0x02000000 0 0x10000000 0x10000000 0 0x2000000
@@ -531,9 +538,10 @@
 		};
 	};
 
-	pci1: pci-controller1 {
+	pci1: pci@1 {
 		compatible = "sandbox,pci";
 		device_type = "pci";
+		bus-range = <0x00 0xff>;
 		#address-cells = <3>;
 		#size-cells = <2>;
 		ranges = <0x02000000 0 0x30000000 0x30000000 0 0x2000
@@ -546,9 +554,10 @@
 		};
 	};
 
-	pci2: pci-controller2 {
+	pci2: pci@2 {
 		compatible = "sandbox,pci";
 		device_type = "pci";
+		bus-range = <0x00 0xff>;
 		#address-cells = <3>;
 		#size-cells = <2>;
 		ranges = <0x02000000 0 0x50000000 0x50000000 0 0x2000
diff --git a/arch/sandbox/include/asm/acpi_table.h b/arch/sandbox/include/asm/acpi_table.h
new file mode 100644
index 0000000..921c7f4
--- /dev/null
+++ b/arch/sandbox/include/asm/acpi_table.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2019 Google LLC
+ */
+
+#ifndef __ASM_ACPI_TABLE_H__
+#define __ASM_ACPI_TABLE_H__
+
+#endif /* __ASM_ACPI_TABLE_H__ */
diff --git a/arch/x86/cpu/apollolake/cpu_spl.c b/arch/x86/cpu/apollolake/cpu_spl.c
index 8a39c31..e2509e3 100644
--- a/arch/x86/cpu/apollolake/cpu_spl.c
+++ b/arch/x86/cpu/apollolake/cpu_spl.c
@@ -6,13 +6,13 @@
  */
 
 #include <common.h>
-#include <acpi_s3.h>
 #include <dm.h>
 #include <ec_commands.h>
 #include <log.h>
 #include <spi_flash.h>
 #include <spl.h>
 #include <syscon.h>
+#include <acpi/acpi_s3.h>
 #include <asm/cpu.h>
 #include <asm/cpu_common.h>
 #include <asm/cpu_x86.h>
diff --git a/arch/x86/cpu/apollolake/fsp_s.c b/arch/x86/cpu/apollolake/fsp_s.c
index 1f22c1e..17cf168 100644
--- a/arch/x86/cpu/apollolake/fsp_s.c
+++ b/arch/x86/cpu/apollolake/fsp_s.c
@@ -5,11 +5,11 @@
  */
 
 #include <common.h>
-#include <acpi_s3.h>
 #include <binman.h>
 #include <dm.h>
 #include <irq.h>
 #include <malloc.h>
+#include <acpi/acpi_s3.h>
 #include <asm/intel_pinctrl.h>
 #include <asm/io.h>
 #include <asm/intel_regs.h>
diff --git a/arch/x86/cpu/apollolake/pmc.c b/arch/x86/cpu/apollolake/pmc.c
index aec0c83..4ea7c74 100644
--- a/arch/x86/cpu/apollolake/pmc.c
+++ b/arch/x86/cpu/apollolake/pmc.c
@@ -9,10 +9,10 @@
 #define LOG_CATEGORY UCLASS_ACPI_PMC
 
 #include <common.h>
-#include <acpi_s3.h>
 #include <dt-structs.h>
 #include <dm.h>
 #include <spl.h>
+#include <acpi/acpi_s3.h>
 #include <asm/io.h>
 #include <asm/pci.h>
 #include <power/acpi_pmc.h>
diff --git a/arch/x86/cpu/baytrail/acpi.c b/arch/x86/cpu/baytrail/acpi.c
index f44228e..5772310 100644
--- a/arch/x86/cpu/baytrail/acpi.c
+++ b/arch/x86/cpu/baytrail/acpi.c
@@ -4,15 +4,15 @@
  */
 
 #include <common.h>
-#include <acpi_s3.h>
 #include <cpu.h>
 #include <dm.h>
-#include <dm/uclass-internal.h>
-#include <asm/acpi_table.h>
+#include <acpi/acpi_s3.h>
+#include <acpi/acpi_table.h>
 #include <asm/io.h>
 #include <asm/tables.h>
 #include <asm/arch/global_nvs.h>
 #include <asm/arch/iomap.h>
+#include <dm/uclass-internal.h>
 
 void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs,
 		      void *dsdt)
diff --git a/arch/x86/cpu/coreboot/timestamp.c b/arch/x86/cpu/coreboot/timestamp.c
index e698200..e8ccaf2 100644
--- a/arch/x86/cpu/coreboot/timestamp.c
+++ b/arch/x86/cpu/coreboot/timestamp.c
@@ -1,8 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * This file is part of the coreboot project.
- *
  * Copyright (C) 2011 The ChromiumOS Authors.  All rights reserved.
+ *
+ * Modified from the coreboot version
  */
 
 #include <common.h>
diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
index dae0694..cec04b4 100644
--- a/arch/x86/cpu/cpu.c
+++ b/arch/x86/cpu/cpu.c
@@ -19,7 +19,6 @@
  */
 
 #include <common.h>
-#include <acpi_s3.h>
 #include <command.h>
 #include <cpu_func.h>
 #include <dm.h>
@@ -27,8 +26,9 @@
 #include <init.h>
 #include <malloc.h>
 #include <syscon.h>
+#include <acpi/acpi_s3.h>
+#include <acpi/acpi_table.h>
 #include <asm/acpi.h>
-#include <asm/acpi_table.h>
 #include <asm/control_regs.h>
 #include <asm/coreboot_tables.h>
 #include <asm/cpu.h>
diff --git a/arch/x86/cpu/intel_common/p2sb.c b/arch/x86/cpu/intel_common/p2sb.c
index d5b4846..6f3c441 100644
--- a/arch/x86/cpu/intel_common/p2sb.c
+++ b/arch/x86/cpu/intel_common/p2sb.c
@@ -92,46 +92,35 @@
 
 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
 	int ret;
+	u32 base[2];
 
+	ret = dev_read_u32_array(dev, "early-regs", base, ARRAY_SIZE(base));
+	if (ret)
+		return log_msg_ret("Missing/short early-regs", ret);
+	plat->mmio_base = base[0];
+	/* TPL sets up the initial BAR */
 	if (spl_phase() == PHASE_TPL) {
-		u32 base[2];
-
-		/* TPL sets up the initial BAR */
-		ret = dev_read_u32_array(dev, "early-regs", base,
-					 ARRAY_SIZE(base));
-		if (ret)
-			return log_msg_ret("Missing/short early-regs", ret);
-		plat->mmio_base = base[0];
 		plat->bdf = pci_get_devfn(dev);
 		if (plat->bdf < 0)
 			return log_msg_ret("Cannot get p2sb PCI address",
 					   plat->bdf);
 	}
+	upriv->mmio_base = plat->mmio_base;
 #else
 	plat->mmio_base = plat->dtplat.early_regs[0];
 	plat->bdf = pci_ofplat_get_devfn(plat->dtplat.reg[0]);
-#endif
 	upriv->mmio_base = plat->mmio_base;
-	debug("p2sb: mmio_base=%x\n", (uint)plat->mmio_base);
+#endif
 
 	return 0;
 }
 
 static int p2sb_probe(struct udevice *dev)
 {
-	if (spl_phase() == PHASE_TPL) {
+	if (spl_phase() == PHASE_TPL)
 		return p2sb_early_init(dev);
-	} else {
-		struct p2sb_platdata *plat = dev_get_platdata(dev);
-
-		plat->mmio_base = dev_read_addr_pci(dev);
-		/* Don't set BDF since it should not be used */
-		if (!plat->mmio_base || plat->mmio_base == FDT_ADDR_T_NONE)
-			return -EINVAL;
-
-		if (spl_phase() == PHASE_SPL)
-			return p2sb_spl_init(dev);
-	}
+	else if (spl_phase() == PHASE_SPL)
+		return p2sb_spl_init(dev);
 
 	return 0;
 }
diff --git a/arch/x86/cpu/quark/acpi.c b/arch/x86/cpu/quark/acpi.c
index 7b6fc2f..26cda3b 100644
--- a/arch/x86/cpu/quark/acpi.c
+++ b/arch/x86/cpu/quark/acpi.c
@@ -4,7 +4,7 @@
  */
 
 #include <common.h>
-#include <asm/acpi_table.h>
+#include <acpi/acpi_table.h>
 #include <asm/tables.h>
 #include <asm/arch/global_nvs.h>
 #include <asm/arch/iomap.h>
diff --git a/arch/x86/cpu/tangier/acpi.c b/arch/x86/cpu/tangier/acpi.c
index 8b12813..4ec8fdd 100644
--- a/arch/x86/cpu/tangier/acpi.c
+++ b/arch/x86/cpu/tangier/acpi.c
@@ -8,13 +8,13 @@
 #include <common.h>
 #include <cpu.h>
 #include <dm.h>
-#include <dm/uclass-internal.h>
-#include <asm/acpi_table.h>
+#include <acpi/acpi_table.h>
 #include <asm/ioapic.h>
 #include <asm/mpspec.h>
 #include <asm/tables.h>
 #include <asm/arch/global_nvs.h>
 #include <asm/arch/iomap.h>
+#include <dm/uclass-internal.h>
 
 void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs,
 		      void *dsdt)
diff --git a/arch/x86/cpu/wakeup.S b/arch/x86/cpu/wakeup.S
index 244ca12..093bf3b 100644
--- a/arch/x86/cpu/wakeup.S
+++ b/arch/x86/cpu/wakeup.S
@@ -5,7 +5,7 @@
  * From coreboot src/arch/x86/wakeup.S
  */
 
-#include <acpi_s3.h>
+#include <acpi/acpi_s3.h>
 #include <asm/processor.h>
 #include <asm/processor-flags.h>
 
diff --git a/arch/x86/dts/chromebook_coral.dts b/arch/x86/dts/chromebook_coral.dts
index af52e11..d48ef35 100644
--- a/arch/x86/dts/chromebook_coral.dts
+++ b/arch/x86/dts/chromebook_coral.dts
@@ -292,7 +292,7 @@
 				reg = <0x50>;
 				compatible = "google,cr50";
 				u-boot,i2c-offset-len = <0>;
-				ready-gpio = <&gpio_n 28 GPIO_ACTIVE_LOW>;
+				ready-gpios = <&gpio_n 28 GPIO_ACTIVE_LOW>;
 				interrupts-extended = <&acpi_gpe 0x3c 0>;
 			};
 		};
diff --git a/arch/x86/include/asm/acpi_table.h b/arch/x86/include/asm/acpi_table.h
index 7588913..928475c 100644
--- a/arch/x86/include/asm/acpi_table.h
+++ b/arch/x86/include/asm/acpi_table.h
@@ -9,381 +9,14 @@
 #ifndef __ASM_ACPI_TABLE_H__
 #define __ASM_ACPI_TABLE_H__
 
-#define RSDP_SIG		"RSD PTR "	/* RSDP pointer signature */
-#define OEM_ID			"U-BOOT"	/* U-Boot */
-#define OEM_TABLE_ID		"U-BOOTBL"	/* U-Boot Table */
-#define ASLC_ID			"INTL"		/* Intel ASL Compiler */
-
-#define ACPI_RSDP_REV_ACPI_1_0	0
-#define ACPI_RSDP_REV_ACPI_2_0	2
-
-/*
- * RSDP (Root System Description Pointer)
- * Note: ACPI 1.0 didn't have length, xsdt_address, and ext_checksum
- */
-struct acpi_rsdp {
-	char signature[8];	/* RSDP signature */
-	u8 checksum;		/* Checksum of the first 20 bytes */
-	char oem_id[6];		/* OEM ID */
-	u8 revision;		/* 0 for ACPI 1.0, others 2 */
-	u32 rsdt_address;	/* Physical address of RSDT (32 bits) */
-	u32 length;		/* Total RSDP length (incl. extended part) */
-	u64 xsdt_address;	/* Physical address of XSDT (64 bits) */
-	u8 ext_checksum;	/* Checksum of the whole table */
-	u8 reserved[3];
-};
-
-/* Generic ACPI header, provided by (almost) all tables */
-struct __packed acpi_table_header {
-	char signature[4];	/* ACPI signature (4 ASCII characters) */
-	u32 length;		/* Table length in bytes (incl. header) */
-	u8 revision;		/* Table version (not ACPI version!) */
-	volatile u8 checksum;	/* To make sum of entire table == 0 */
-	char oem_id[6];		/* OEM identification */
-	char oem_table_id[8];	/* OEM table identification */
-	u32 oem_revision;	/* OEM revision number */
-	char aslc_id[4];	/* ASL compiler vendor ID */
-	u32 aslc_revision;	/* ASL compiler revision number */
-};
-
-/* A maximum number of 32 ACPI tables ought to be enough for now */
-#define MAX_ACPI_TABLES		32
-
-/* RSDT (Root System Description Table) */
-struct acpi_rsdt {
-	struct acpi_table_header header;
-	u32 entry[MAX_ACPI_TABLES];
-};
-
-/* XSDT (Extended System Description Table) */
-struct acpi_xsdt {
-	struct acpi_table_header header;
-	u64 entry[MAX_ACPI_TABLES];
-};
-
-/* FADT Preferred Power Management Profile */
-enum acpi_pm_profile {
-	ACPI_PM_UNSPECIFIED = 0,
-	ACPI_PM_DESKTOP,
-	ACPI_PM_MOBILE,
-	ACPI_PM_WORKSTATION,
-	ACPI_PM_ENTERPRISE_SERVER,
-	ACPI_PM_SOHO_SERVER,
-	ACPI_PM_APPLIANCE_PC,
-	ACPI_PM_PERFORMANCE_SERVER,
-	ACPI_PM_TABLET
-};
-
-/* FADT flags for p_lvl2_lat and p_lvl3_lat */
-#define ACPI_FADT_C2_NOT_SUPPORTED	101
-#define ACPI_FADT_C3_NOT_SUPPORTED	1001
-
-/* FADT Boot Architecture Flags */
-#define ACPI_FADT_LEGACY_FREE		0x00
-#define ACPI_FADT_LEGACY_DEVICES	(1 << 0)
-#define ACPI_FADT_8042			(1 << 1)
-#define ACPI_FADT_VGA_NOT_PRESENT	(1 << 2)
-#define ACPI_FADT_MSI_NOT_SUPPORTED	(1 << 3)
-#define ACPI_FADT_NO_PCIE_ASPM_CONTROL	(1 << 4)
-
-/* FADT Feature Flags */
-#define ACPI_FADT_WBINVD		(1 << 0)
-#define ACPI_FADT_WBINVD_FLUSH		(1 << 1)
-#define ACPI_FADT_C1_SUPPORTED		(1 << 2)
-#define ACPI_FADT_C2_MP_SUPPORTED	(1 << 3)
-#define ACPI_FADT_POWER_BUTTON		(1 << 4)
-#define ACPI_FADT_SLEEP_BUTTON		(1 << 5)
-#define ACPI_FADT_FIXED_RTC		(1 << 6)
-#define ACPI_FADT_S4_RTC_WAKE		(1 << 7)
-#define ACPI_FADT_32BIT_TIMER		(1 << 8)
-#define ACPI_FADT_DOCKING_SUPPORTED	(1 << 9)
-#define ACPI_FADT_RESET_REGISTER	(1 << 10)
-#define ACPI_FADT_SEALED_CASE		(1 << 11)
-#define ACPI_FADT_HEADLESS		(1 << 12)
-#define ACPI_FADT_SLEEP_TYPE		(1 << 13)
-#define ACPI_FADT_PCI_EXPRESS_WAKE	(1 << 14)
-#define ACPI_FADT_PLATFORM_CLOCK	(1 << 15)
-#define ACPI_FADT_S4_RTC_VALID		(1 << 16)
-#define ACPI_FADT_REMOTE_POWER_ON	(1 << 17)
-#define ACPI_FADT_APIC_CLUSTER		(1 << 18)
-#define ACPI_FADT_APIC_PHYSICAL		(1 << 19)
-#define ACPI_FADT_HW_REDUCED_ACPI	(1 << 20)
-#define ACPI_FADT_LOW_PWR_IDLE_S0	(1 << 21)
-
-enum acpi_address_space_type {
-	ACPI_ADDRESS_SPACE_MEMORY = 0,	/* System memory */
-	ACPI_ADDRESS_SPACE_IO,		/* System I/O */
-	ACPI_ADDRESS_SPACE_PCI,		/* PCI config space */
-	ACPI_ADDRESS_SPACE_EC,		/* Embedded controller */
-	ACPI_ADDRESS_SPACE_SMBUS,	/* SMBus */
-	ACPI_ADDRESS_SPACE_PCC = 0x0a,	/* Platform Comm. Channel */
-	ACPI_ADDRESS_SPACE_FIXED = 0x7f	/* Functional fixed hardware */
-};
-
-enum acpi_address_space_size {
-	ACPI_ACCESS_SIZE_UNDEFINED = 0,
-	ACPI_ACCESS_SIZE_BYTE_ACCESS,
-	ACPI_ACCESS_SIZE_WORD_ACCESS,
-	ACPI_ACCESS_SIZE_DWORD_ACCESS,
-	ACPI_ACCESS_SIZE_QWORD_ACCESS
-};
-
-struct acpi_gen_regaddr {
-	u8 space_id;	/* Address space ID */
-	u8 bit_width;	/* Register size in bits */
-	u8 bit_offset;	/* Register bit offset */
-	u8 access_size;	/* Access size */
-	u32 addrl;	/* Register address, low 32 bits */
-	u32 addrh;	/* Register address, high 32 bits */
-};
-
-/* FADT (Fixed ACPI Description Table) */
-struct __packed acpi_fadt {
-	struct acpi_table_header header;
-	u32 firmware_ctrl;
-	u32 dsdt;
-	u8 res1;
-	u8 preferred_pm_profile;
-	u16 sci_int;
-	u32 smi_cmd;
-	u8 acpi_enable;
-	u8 acpi_disable;
-	u8 s4bios_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 p_lvl2_lat;
-	u16 p_lvl3_lat;
-	u16 flush_size;
-	u16 flush_stride;
-	u8 duty_offset;
-	u8 duty_width;
-	u8 day_alrm;
-	u8 mon_alrm;
-	u8 century;
-	u16 iapc_boot_arch;
-	u8 res2;
-	u32 flags;
-	struct acpi_gen_regaddr reset_reg;
-	u8 reset_value;
-	u16 arm_boot_arch;
-	u8 minor_revision;
-	u32 x_firmware_ctl_l;
-	u32 x_firmware_ctl_h;
-	u32 x_dsdt_l;
-	u32 x_dsdt_h;
-	struct acpi_gen_regaddr x_pm1a_evt_blk;
-	struct acpi_gen_regaddr x_pm1b_evt_blk;
-	struct acpi_gen_regaddr x_pm1a_cnt_blk;
-	struct acpi_gen_regaddr x_pm1b_cnt_blk;
-	struct acpi_gen_regaddr x_pm2_cnt_blk;
-	struct acpi_gen_regaddr x_pm_tmr_blk;
-	struct acpi_gen_regaddr x_gpe0_blk;
-	struct acpi_gen_regaddr x_gpe1_blk;
-};
-
-/* FACS flags */
-#define ACPI_FACS_S4BIOS_F	(1 << 0)
-#define ACPI_FACS_64BIT_WAKE_F	(1 << 1)
-
-/* FACS (Firmware ACPI Control Structure) */
-struct acpi_facs {
-	char signature[4];		/* "FACS" */
-	u32 length;			/* Length in bytes (>= 64) */
-	u32 hardware_signature;		/* Hardware signature */
-	u32 firmware_waking_vector;	/* Firmware waking vector */
-	u32 global_lock;		/* Global lock */
-	u32 flags;			/* FACS flags */
-	u32 x_firmware_waking_vector_l;	/* X FW waking vector, low */
-	u32 x_firmware_waking_vector_h;	/* X FW waking vector, high */
-	u8 version;			/* Version 2 */
-	u8 res1[3];
-	u32 ospm_flags;			/* OSPM enabled flags */
-	u8 res2[24];
-};
-
-/* MADT flags */
-#define ACPI_MADT_PCAT_COMPAT	(1 << 0)
-
-/* MADT (Multiple APIC Description Table) */
-struct acpi_madt {
-	struct acpi_table_header header;
-	u32 lapic_addr;			/* Local APIC address */
-	u32 flags;			/* Multiple APIC flags */
-};
-
-/* MADT: APIC Structure Type*/
-enum acpi_apic_types {
-	ACPI_APIC_LAPIC	= 0,		/* Processor local APIC */
-	ACPI_APIC_IOAPIC,		/* I/O APIC */
-	ACPI_APIC_IRQ_SRC_OVERRIDE,	/* Interrupt source override */
-	ACPI_APIC_NMI_SRC,		/* NMI source */
-	ACPI_APIC_LAPIC_NMI,		/* Local APIC NMI */
-	ACPI_APIC_LAPIC_ADDR_OVERRIDE,	/* Local APIC address override */
-	ACPI_APIC_IOSAPIC,		/* I/O SAPIC */
-	ACPI_APIC_LSAPIC,		/* Local SAPIC */
-	ACPI_APIC_PLATFORM_IRQ_SRC,	/* Platform interrupt sources */
-	ACPI_APIC_LX2APIC,		/* Processor local x2APIC */
-	ACPI_APIC_LX2APIC_NMI,		/* Local x2APIC NMI */
-};
-
-/* MADT: Processor Local APIC Structure */
-
-#define LOCAL_APIC_FLAG_ENABLED	(1 << 0)
-
-struct acpi_madt_lapic {
-	u8 type;		/* Type (0) */
-	u8 length;		/* Length in bytes (8) */
-	u8 processor_id;	/* ACPI processor ID */
-	u8 apic_id;		/* Local APIC ID */
-	u32 flags;		/* Local APIC flags */
-};
-
-/* MADT: I/O APIC Structure */
-struct acpi_madt_ioapic {
-	u8 type;		/* Type (1) */
-	u8 length;		/* Length in bytes (12) */
-	u8 ioapic_id;		/* I/O APIC ID */
-	u8 reserved;
-	u32 ioapic_addr;	/* I/O APIC address */
-	u32 gsi_base;		/* Global system interrupt base */
-};
-
-/* MADT: Interrupt Source Override Structure */
-struct __packed acpi_madt_irqoverride {
-	u8 type;		/* Type (2) */
-	u8 length;		/* Length in bytes (10) */
-	u8 bus;			/* ISA (0) */
-	u8 source;		/* Bus-relative int. source (IRQ) */
-	u32 gsirq;		/* Global system interrupt */
-	u16 flags;		/* MPS INTI flags */
-};
-
-/* MADT: Local APIC NMI Structure */
-struct __packed acpi_madt_lapic_nmi {
-	u8 type;		/* Type (4) */
-	u8 length;		/* Length in bytes (6) */
-	u8 processor_id;	/* ACPI processor ID */
-	u16 flags;		/* MPS INTI flags */
-	u8 lint;		/* Local APIC LINT# */
-};
-
-/* MCFG (PCI Express MMIO config space BAR description table) */
-struct acpi_mcfg {
-	struct acpi_table_header header;
-	u8 reserved[8];
-};
-
-struct acpi_mcfg_mmconfig {
-	u32 base_address_l;
-	u32 base_address_h;
-	u16 pci_segment_group_number;
-	u8 start_bus_number;
-	u8 end_bus_number;
-	u8 reserved[4];
-};
-
-/* PM1_CNT bit defines */
-#define PM1_CNT_SCI_EN		(1 << 0)
-
-/* ACPI global NVS structure */
+struct acpi_facs;
+struct acpi_fadt;
 struct acpi_global_nvs;
-
-/* CSRT (Core System Resource Table) */
-struct acpi_csrt {
-	struct acpi_table_header header;
-};
-
-struct acpi_csrt_group {
-	u32 length;
-	u32 vendor_id;
-	u32 subvendor_id;
-	u16 device_id;
-	u16 subdevice_id;
-	u16 revision;
-	u16 reserved;
-	u32 shared_info_length;
-};
-
-struct acpi_csrt_shared_info {
-	u16 major_version;
-	u16 minor_version;
-	u32 mmio_base_low;
-	u32 mmio_base_high;
-	u32 gsi_interrupt;
-	u8 interrupt_polarity;
-	u8 interrupt_mode;
-	u8 num_channels;
-	u8 dma_address_width;
-	u16 base_request_line;
-	u16 num_handshake_signals;
-	u32 max_block_size;
-};
-
-/* DBG2 definitions are partially used for SPCR interface_type */
-
-/* Types for port_type field */
-
-#define ACPI_DBG2_SERIAL_PORT		0x8000
-#define ACPI_DBG2_1394_PORT		0x8001
-#define ACPI_DBG2_USB_PORT		0x8002
-#define ACPI_DBG2_NET_PORT		0x8003
-
-/* Subtypes for port_subtype field */
-
-#define ACPI_DBG2_16550_COMPATIBLE	0x0000
-#define ACPI_DBG2_16550_SUBSET		0x0001
-#define ACPI_DBG2_ARM_PL011		0x0003
-#define ACPI_DBG2_ARM_SBSA_32BIT	0x000D
-#define ACPI_DBG2_ARM_SBSA_GENERIC	0x000E
-#define ACPI_DBG2_ARM_DCC		0x000F
-#define ACPI_DBG2_BCM2835		0x0010
-
-#define ACPI_DBG2_1394_STANDARD		0x0000
-
-#define ACPI_DBG2_USB_XHCI		0x0000
-#define ACPI_DBG2_USB_EHCI		0x0001
-
-#define ACPI_DBG2_UNKNOWN		0x00FF
-
-/* SPCR (Serial Port Console Redirection table) */
-struct __packed acpi_spcr {
-	struct acpi_table_header header;
-	u8 interface_type;
-	u8 reserved[3];
-	struct acpi_gen_regaddr serial_port;
-	u8 interrupt_type;
-	u8 pc_interrupt;
-	u32 interrupt;		/* Global system interrupt */
-	u8 baud_rate;
-	u8 parity;
-	u8 stop_bits;
-	u8 flow_control;
-	u8 terminal_type;
-	u8 reserved1;
-	u16 pci_device_id;	/* Must be 0xffff if not PCI device */
-	u16 pci_vendor_id;	/* Must be 0xffff if not PCI device */
-	u8 pci_bus;
-	u8 pci_device;
-	u8 pci_function;
-	u32 pci_flags;
-	u8 pci_segment;
-	u32 reserved2;
-};
+struct acpi_madt_ioapic;
+struct acpi_madt_irqoverride;
+struct acpi_madt_lapic_nmi;
+struct acpi_mcfg_mmconfig;
+struct acpi_table_header;
 
 /* These can be used by the target port */
 
diff --git a/arch/x86/include/asm/arch-apollolake/global_nvs.h b/arch/x86/include/asm/arch-apollolake/global_nvs.h
new file mode 100644
index 0000000..fe62194
--- /dev/null
+++ b/arch/x86/include/asm/arch-apollolake/global_nvs.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2015-2017 Intel Corp.
+ * (Written by Lance Zhao <lijian.zhao@intel.com> for Intel Corp.)
+ * Copyright Google LLC 2019
+ *
+ * Modified from coreboot apollolake/include/soc/nvs.h
+ */
+
+#ifndef _GLOBAL_NVS_H_
+#define _GLOBAL_NVS_H_
+
+struct __packed acpi_global_nvs {
+	/* Miscellaneous */
+	u8	pcnt; /* 0x00 - Processor Count */
+	u8	ppcm; /* 0x01 - Max PPC State */
+	u8	lids; /* 0x02 - LID State */
+	u8	pwrs; /* 0x03 - AC Power State */
+	u8	dpte; /* 0x04 - Enable DPTF */
+	u32	cbmc; /* 0x05 - 0x08 - U-Boot Console */
+	u64	pm1i; /* 0x09 - 0x10 - System Wake Source - PM1 Index */
+	u64	gpei; /* 0x11 - 0x18 - GPE Wake Source */
+	u64	nhla; /* 0x19 - 0x20 - NHLT Address */
+	u32	nhll; /* 0x21 - 0x24 - NHLT Length */
+	u32	prt0; /* 0x25 - 0x28 - PERST_0 Address */
+	u8	scdp; /* 0x29 - SD_CD GPIO portid */
+	u8	scdo; /* 0x2a - GPIO pad offset relative to the community */
+	u8	uior; /* 0x2b - UART debug controller init on S3 resume */
+	u8	ecps; /* 0x2c - SGX Enabled status */
+	u64	emna; /* 0x2d - 0x34 EPC base address */
+	u64	elng; /* 0x35 - 0x3c EPC Length */
+	u8	unused1[0x100 - 0x3d];		/* Pad out to 256 bytes */
+	u8	unused2[0x1000 - 0x100];	/* Pad out to 4096 bytes */
+};
+
+#endif /* _GLOBAL_NVS_H_ */
diff --git a/arch/x86/include/asm/arch-coreboot/timestamp.h b/arch/x86/include/asm/arch-coreboot/timestamp.h
index 9320afb..85d42c0 100644
--- a/arch/x86/include/asm/arch-coreboot/timestamp.h
+++ b/arch/x86/include/asm/arch-coreboot/timestamp.h
@@ -1,8 +1,8 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * This file is part of the coreboot project.
- *
  * Copyright (C) 2011 The ChromiumOS Authors.  All rights reserved.
+ *
+ * Taken from the coreboot version
  */
 
 #ifndef __COREBOOT_TIMESTAMP_H__
diff --git a/arch/x86/include/asm/intel_pinctrl_defs.h b/arch/x86/include/asm/intel_pinctrl_defs.h
index 6da06bb..1ea141f 100644
--- a/arch/x86/include/asm/intel_pinctrl_defs.h
+++ b/arch/x86/include/asm/intel_pinctrl_defs.h
@@ -1,7 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * This file is part of the coreboot project.
- *
  * Copyright (C) 2015-2016 Intel Corp.
  * Copyright 2019 Google LLC
  *
diff --git a/arch/x86/lib/acpi.c b/arch/x86/lib/acpi.c
index cba9c24..7431458 100644
--- a/arch/x86/lib/acpi.c
+++ b/arch/x86/lib/acpi.c
@@ -4,7 +4,7 @@
  */
 
 #include <common.h>
-#include <asm/acpi_table.h>
+#include <acpi/acpi_table.h>
 #include <asm/io.h>
 #include <asm/tables.h>
 
diff --git a/arch/x86/lib/acpi_s3.c b/arch/x86/lib/acpi_s3.c
index 197636c..52410a5 100644
--- a/arch/x86/lib/acpi_s3.c
+++ b/arch/x86/lib/acpi_s3.c
@@ -4,9 +4,9 @@
  */
 
 #include <common.h>
-#include <acpi_s3.h>
+#include <acpi/acpi_s3.h>
+#include <acpi/acpi_table.h>
 #include <asm/acpi.h>
-#include <asm/acpi_table.h>
 #include <asm/post.h>
 #include <linux/linkage.h>
 
diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c
index 66e32f2..9346e16 100644
--- a/arch/x86/lib/acpi_table.c
+++ b/arch/x86/lib/acpi_table.c
@@ -12,8 +12,8 @@
 #include <dm/uclass-internal.h>
 #include <serial.h>
 #include <version.h>
+#include <acpi/acpi_table.h>
 #include <asm/acpi/global_nvs.h>
-#include <asm/acpi_table.h>
 #include <asm/ioapic.h>
 #include <asm/lapic.h>
 #include <asm/mpspec.h>
@@ -471,6 +471,15 @@
 	spcr->pci_device_id = 0xffff;
 	spcr->pci_vendor_id = 0xffff;
 
+	/*
+	 * SPCR has no clue if the UART base clock speed is different
+	 * to the default one. However, the SPCR 1.04 defines baud rate
+	 * 0 as a preconfigured state of UART and OS is supposed not
+	 * to touch the configuration of the serial device.
+	 */
+	if (serial_info.clock != SERIAL_DEFAULT_CLOCK)
+		spcr->baud_rate = 0;
+
 	/* Fix checksum */
 	header->checksum = table_compute_checksum((void *)spcr, header->length);
 }
diff --git a/arch/x86/lib/coreboot_table.c b/arch/x86/lib/coreboot_table.c
index 2943e11..c996fc5 100644
--- a/arch/x86/lib/coreboot_table.c
+++ b/arch/x86/lib/coreboot_table.c
@@ -4,9 +4,9 @@
  */
 
 #include <common.h>
-#include <acpi_s3.h>
 #include <malloc.h>
 #include <vbe.h>
+#include <acpi/acpi_s3.h>
 #include <asm/coreboot_tables.h>
 #include <asm/e820.h>
 
diff --git a/arch/x86/lib/fsp/fsp_common.c b/arch/x86/lib/fsp/fsp_common.c
index 5eff0f9..267527e 100644
--- a/arch/x86/lib/fsp/fsp_common.c
+++ b/arch/x86/lib/fsp/fsp_common.c
@@ -4,11 +4,11 @@
  */
 
 #include <common.h>
-#include <acpi_s3.h>
 #include <cpu_func.h>
 #include <dm.h>
 #include <errno.h>
 #include <rtc.h>
+#include <acpi/acpi_s3.h>
 #include <asm/cmos_layout.h>
 #include <asm/early_cmos.h>
 #include <asm/io.h>
diff --git a/arch/x86/lib/fsp1/fsp_common.c b/arch/x86/lib/fsp1/fsp_common.c
index aee2a05..0a72680 100644
--- a/arch/x86/lib/fsp1/fsp_common.c
+++ b/arch/x86/lib/fsp1/fsp_common.c
@@ -4,11 +4,11 @@
  */
 
 #include <common.h>
-#include <acpi_s3.h>
 #include <dm.h>
 #include <errno.h>
 #include <malloc.h>
 #include <rtc.h>
+#include <acpi/acpi_s3.h>
 #include <asm/cmos_layout.h>
 #include <asm/early_cmos.h>
 #include <asm/io.h>
diff --git a/arch/x86/lib/fsp2/fsp_dram.c b/arch/x86/lib/fsp2/fsp_dram.c
index 90a238a..c8f2c09 100644
--- a/arch/x86/lib/fsp2/fsp_dram.c
+++ b/arch/x86/lib/fsp2/fsp_dram.c
@@ -5,9 +5,9 @@
  */
 
 #include <common.h>
-#include <acpi_s3.h>
 #include <handoff.h>
 #include <spl.h>
+#include <acpi/acpi_s3.h>
 #include <asm/arch/cpu.h>
 #include <asm/fsp/fsp_support.h>
 #include <asm/fsp2/fsp_api.h>
diff --git a/arch/x86/lib/tables.c b/arch/x86/lib/tables.c
index 7aea722..574d331 100644
--- a/arch/x86/lib/tables.c
+++ b/arch/x86/lib/tables.c
@@ -6,10 +6,10 @@
 #include <common.h>
 #include <malloc.h>
 #include <smbios.h>
+#include <acpi/acpi_table.h>
 #include <asm/sfi.h>
 #include <asm/mpspec.h>
 #include <asm/tables.h>
-#include <asm/acpi_table.h>
 #include <asm/coreboot_tables.h>
 
 /**
diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c
index 9b5e767..ffc0963 100644
--- a/arch/x86/lib/zimage.c
+++ b/arch/x86/lib/zimage.c
@@ -16,7 +16,7 @@
 #include <env.h>
 #include <irq_func.h>
 #include <malloc.h>
-#include <asm/acpi_table.h>
+#include <acpi/acpi_table.h>
 #include <asm/io.h>
 #include <asm/ptrace.h>
 #include <asm/zimage.h>
diff --git a/board/dhelectronics/dh_stm32mp1/board.c b/board/dhelectronics/dh_stm32mp1/board.c
index 7bcd713..3225581 100644
--- a/board/dhelectronics/dh_stm32mp1/board.c
+++ b/board/dhelectronics/dh_stm32mp1/board.c
@@ -118,7 +118,7 @@
 
 	if (IS_ENABLED(CONFIG_STM32MP1_OPTEE))
 		mode = "trusted with OP-TEE";
-	else if (IS_ENABLED(CONFIG_STM32MP1_TRUSTED))
+	else if (IS_ENABLED(CONFIG_TFABOOT))
 		mode = "trusted";
 	else
 		mode = "basic";
@@ -283,7 +283,7 @@
 
 static void sysconf_init(void)
 {
-#ifndef CONFIG_STM32MP1_TRUSTED
+#ifndef CONFIG_TFABOOT
 	u8 *syscfg;
 #ifdef CONFIG_DM_REGULATOR
 	struct udevice *pwr_dev;
@@ -375,6 +375,56 @@
 #endif
 }
 
+static void board_init_fmc2(void)
+{
+#define STM32_FMC2_BCR1			0x0
+#define STM32_FMC2_BTR1			0x4
+#define STM32_FMC2_BWTR1		0x104
+#define STM32_FMC2_BCR(x)		((x) * 0x8 + STM32_FMC2_BCR1)
+#define STM32_FMC2_BCRx_FMCEN		BIT(31)
+#define STM32_FMC2_BCRx_WREN		BIT(12)
+#define STM32_FMC2_BCRx_RSVD		BIT(7)
+#define STM32_FMC2_BCRx_FACCEN		BIT(6)
+#define STM32_FMC2_BCRx_MWID(n)		((n) << 4)
+#define STM32_FMC2_BCRx_MTYP(n)		((n) << 2)
+#define STM32_FMC2_BCRx_MUXEN		BIT(1)
+#define STM32_FMC2_BCRx_MBKEN		BIT(0)
+#define STM32_FMC2_BTR(x)		((x) * 0x8 + STM32_FMC2_BTR1)
+#define STM32_FMC2_BTRx_DATAHLD(n)	((n) << 30)
+#define STM32_FMC2_BTRx_BUSTURN(n)	((n) << 16)
+#define STM32_FMC2_BTRx_DATAST(n)	((n) << 8)
+#define STM32_FMC2_BTRx_ADDHLD(n)	((n) << 4)
+#define STM32_FMC2_BTRx_ADDSET(n)	((n) << 0)
+
+#define RCC_MP_AHB6RSTCLRR		0x218
+#define RCC_MP_AHB6RSTCLRR_FMCRST	BIT(12)
+#define RCC_MP_AHB6ENSETR		0x19c
+#define RCC_MP_AHB6ENSETR_FMCEN		BIT(12)
+
+	const u32 bcr = STM32_FMC2_BCRx_WREN |STM32_FMC2_BCRx_RSVD |
+			STM32_FMC2_BCRx_FACCEN | STM32_FMC2_BCRx_MWID(1) |
+			STM32_FMC2_BCRx_MTYP(2) | STM32_FMC2_BCRx_MUXEN |
+			STM32_FMC2_BCRx_MBKEN;
+	const u32 btr = STM32_FMC2_BTRx_DATAHLD(3) |
+			STM32_FMC2_BTRx_BUSTURN(2) |
+			STM32_FMC2_BTRx_DATAST(0x22) |
+			STM32_FMC2_BTRx_ADDHLD(2) |
+			STM32_FMC2_BTRx_ADDSET(2);
+
+	/* Set up FMC2 bus for KS8851-16MLL and X11 SRAM */
+	writel(RCC_MP_AHB6RSTCLRR_FMCRST, STM32_RCC_BASE + RCC_MP_AHB6RSTCLRR);
+	writel(RCC_MP_AHB6ENSETR_FMCEN, STM32_RCC_BASE + RCC_MP_AHB6ENSETR);
+
+	/* KS8851-16MLL -- Muxed mode */
+	writel(bcr, STM32_FMC2_BASE + STM32_FMC2_BCR(1));
+	writel(btr, STM32_FMC2_BASE + STM32_FMC2_BTR(1));
+	/* AS7C34098 SRAM on X11 -- Muxed mode */
+	writel(bcr, STM32_FMC2_BASE + STM32_FMC2_BCR(3));
+	writel(btr, STM32_FMC2_BASE + STM32_FMC2_BTR(3));
+
+	setbits_le32(STM32_FMC2_BASE + STM32_FMC2_BCR1, STM32_FMC2_BCRx_FMCEN);
+}
+
 /* board dependent setup after realloc */
 int board_init(void)
 {
@@ -398,7 +448,9 @@
 
 	sysconf_init();
 
-	if (CONFIG_IS_ENABLED(CONFIG_LED))
+	board_init_fmc2();
+
+	if (CONFIG_IS_ENABLED(LED))
 		led_default_state();
 
 	return 0;
diff --git a/board/sandbox/sandbox.c b/board/sandbox/sandbox.c
index 0c3d245..1372003 100644
--- a/board/sandbox/sandbox.c
+++ b/board/sandbox/sandbox.c
@@ -58,6 +58,12 @@
 	return 0;
 }
 
+int ft_board_setup(void *fdt, bd_t *bd)
+{
+	/* Create an arbitrary reservation to allow testing OF_BOARD_SETUP.*/
+	return fdt_add_mem_rsv(fdt, 0x00d02000, 0x4000);
+}
+
 #ifdef CONFIG_BOARD_LATE_INIT
 int board_late_init(void)
 {
diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
index 07f5344..45068b1 100644
--- a/board/st/stm32mp1/stm32mp1.c
+++ b/board/st/stm32mp1/stm32mp1.c
@@ -92,7 +92,7 @@
 
 	if (IS_ENABLED(CONFIG_STM32MP1_OPTEE))
 		mode = "trusted with OP-TEE";
-	else if (IS_ENABLED(CONFIG_STM32MP1_TRUSTED))
+	else if (IS_ENABLED(TFABOOT))
 		mode = "trusted";
 	else
 		mode = "basic";
@@ -462,7 +462,7 @@
 
 static void sysconf_init(void)
 {
-#ifndef CONFIG_STM32MP1_TRUSTED
+#ifndef CONFIG_TFABOOT
 	u8 *syscfg;
 #ifdef CONFIG_DM_REGULATOR
 	struct udevice *pwr_dev;
@@ -647,7 +647,7 @@
 
 	sysconf_init();
 
-	if (CONFIG_IS_ENABLED(CONFIG_LED))
+	if (CONFIG_IS_ENABLED(LED))
 		led_default_state();
 
 	return 0;
diff --git a/cmd/fdt.c b/cmd/fdt.c
index 25a6ed4..36cc726 100644
--- a/cmd/fdt.c
+++ b/cmd/fdt.c
@@ -286,7 +286,7 @@
 	/*
 	 * Set the value of a property in the working_fdt.
 	 */
-	} else if (argv[1][0] == 's') {
+	} else if (strncmp(argv[1], "se", 2) == 0) {
 		char *pathp;		/* path */
 		char *prop;		/* property */
 		int  nodeoffset;	/* node offset from libfdt */
diff --git a/common/Kconfig b/common/Kconfig
index 3072651..ee4f748 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -775,9 +775,16 @@
 	  log message is shown - other details like level, category, file and
 	  line number are omitted.
 
+config LOG_SYSLOG
+	bool "Log output to syslog server"
+	depends on LOG && NET
+	help
+	  Enables a log driver which broadcasts log records via UDP port 514
+	  to syslog servers.
+
 config LOG_TEST
 	bool "Provide a test for logging"
-	depends on LOG
+	depends on LOG && UNIT_TEST
 	default y if SANDBOX
 	help
 	  This enables a 'log test' command to test logging. It is normally
diff --git a/common/Makefile b/common/Makefile
index 702f239..d84e10b 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -132,6 +132,7 @@
 obj-y += command.o
 obj-$(CONFIG_$(SPL_TPL_)LOG) += log.o
 obj-$(CONFIG_$(SPL_TPL_)LOG_CONSOLE) += log_console.o
+obj-$(CONFIG_$(SPL_TPL_)LOG_SYSLOG) += log_syslog.o
 obj-y += s_record.o
 obj-$(CONFIG_CMD_LOADB) += xyzModem.o
 obj-$(CONFIG_$(SPL_TPL_)YMODEM_SUPPORT) += xyzModem.o
diff --git a/common/log_syslog.c b/common/log_syslog.c
new file mode 100644
index 0000000..5e3e20e
--- /dev/null
+++ b/common/log_syslog.c
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Log to syslog.
+ *
+ * Copyright (c) 2020, Heinrich Schuchardt <xypron.glpk@gmx.de>
+ */
+
+#include <common.h>
+#include <log.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define BUFFER_SIZE 480
+
+static void append(char **buf, char *buf_end, const char *fmt, ...)
+{
+	va_list args;
+	size_t size = buf_end - *buf;
+
+	va_start(args, fmt);
+	vsnprintf(*buf, size, fmt, args);
+	va_end(args);
+	*buf += strlen(*buf);
+}
+
+static int log_syslog_emit(struct log_device *ldev, struct log_rec *rec)
+{
+	int ret;
+	int fmt = gd->log_fmt;
+	char msg[BUFFER_SIZE];
+	char *msg_end = msg + BUFFER_SIZE;
+	char *ptr = msg;
+	char *iphdr;
+	char *log_msg;
+	int eth_hdr_size;
+	struct in_addr bcast_ip;
+	static int processing_msg;
+	unsigned int log_level;
+	char *log_hostname;
+
+	/* Fend off messages from the network stack while writing a message */
+	if (processing_msg)
+		return 0;
+
+	processing_msg = 1;
+
+	/* Setup packet buffers */
+	net_init();
+	/* Disable hardware and put it into the reset state */
+	eth_halt();
+	/* Set current device according to environment variables */
+	eth_set_current();
+	/* Get hardware ready for send and receive operations */
+	ret = eth_init();
+	if (ret < 0) {
+		eth_halt();
+		goto out;
+	}
+
+	memset(msg, 0, BUFFER_SIZE);
+
+	/* Set ethernet header */
+	eth_hdr_size = net_set_ether((uchar *)ptr, net_bcast_ethaddr, PROT_IP);
+	ptr += eth_hdr_size;
+	iphdr = ptr;
+	ptr += IP_UDP_HDR_SIZE;
+	log_msg = ptr;
+
+	/*
+	 * The syslog log levels defined in RFC 5424 match the U-Boot ones up to
+	 * level 7 (debug).
+	 */
+	log_level = rec->level;
+	if (log_level > 7)
+		log_level = 7;
+	/* Leave high bits as 0 to write a 'kernel message' */
+
+	/* Write log message to buffer */
+	append(&ptr, msg_end, "<%u>", log_level);
+	log_hostname = env_get("log_hostname");
+	if (log_hostname)
+		append(&ptr, msg_end, "%s ", log_hostname);
+	append(&ptr, msg_end, "uboot: ");
+	if (fmt & (1 << LOGF_LEVEL))
+		append(&ptr, msg_end, "%s.",
+		       log_get_level_name(rec->level));
+	if (fmt & (1 << LOGF_CAT))
+		append(&ptr, msg_end, "%s,",
+		       log_get_cat_name(rec->cat));
+	if (fmt & (1 << LOGF_FILE))
+		append(&ptr, msg_end, "%s:", rec->file);
+	if (fmt & (1 << LOGF_LINE))
+		append(&ptr, msg_end, "%d-", rec->line);
+	if (fmt & (1 << LOGF_FUNC))
+		append(&ptr, msg_end, "%s()", rec->func);
+	if (fmt & (1 << LOGF_MSG))
+		append(&ptr, msg_end, "%s%s",
+		       fmt != (1 << LOGF_MSG) ? " " : "", rec->msg);
+	/* Consider trailing 0x00 */
+	ptr++;
+
+	debug("log message: '%s'\n", log_msg);
+
+	/* Broadcast message */
+	bcast_ip.s_addr = 0xFFFFFFFFL;
+	net_set_udp_header((uchar *)iphdr, bcast_ip, 514, 514, ptr - log_msg);
+	net_send_packet((uchar *)msg, ptr - msg);
+
+out:
+	processing_msg = 0;
+	return ret;
+}
+
+LOG_DRIVER(syslog) = {
+	.name	= "syslog",
+	.emit	= log_syslog_emit,
+};
diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig
index 60fbc9a..9d09233 100644
--- a/configs/sandbox64_defconfig
+++ b/configs/sandbox64_defconfig
@@ -18,10 +18,12 @@
 CONFIG_SILENT_CONSOLE=y
 CONFIG_PRE_CONSOLE_BUFFER=y
 CONFIG_LOG_MAX_LEVEL=6
+CONFIG_LOG_SYSLOG=y
 CONFIG_DISPLAY_BOARDINFO_LATE=y
 CONFIG_CMD_CPU=y
 CONFIG_CMD_LICENSE=y
 CONFIG_CMD_BOOTZ=y
+CONFIG_CMD_BOOTEFI_HELLO=y
 # CONFIG_CMD_ELF is not set
 CONFIG_CMD_ASKENV=y
 CONFIG_CMD_GREPENV=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 72e1de3..cc38315 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -19,12 +19,14 @@
 CONFIG_SILENT_CONSOLE=y
 CONFIG_PRE_CONSOLE_BUFFER=y
 CONFIG_LOG_MAX_LEVEL=6
+CONFIG_LOG_SYSLOG=y
 CONFIG_LOG_ERROR_RETURN=y
 CONFIG_DISPLAY_BOARDINFO_LATE=y
 CONFIG_ANDROID_AB=y
 CONFIG_CMD_CPU=y
 CONFIG_CMD_LICENSE=y
 CONFIG_CMD_BOOTZ=y
+CONFIG_CMD_BOOTEFI_HELLO=y
 CONFIG_CMD_ABOOTIMG=y
 # CONFIG_CMD_ELF is not set
 CONFIG_CMD_ASKENV=y
diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig
index 59d34cb..00d9359 100644
--- a/configs/sandbox_flattree_defconfig
+++ b/configs/sandbox_flattree_defconfig
@@ -15,10 +15,12 @@
 CONFIG_CONSOLE_RECORD_OUT_SIZE=0x1000
 CONFIG_SILENT_CONSOLE=y
 CONFIG_LOG_MAX_LEVEL=6
+CONFIG_LOG_SYSLOG=y
 CONFIG_DISPLAY_BOARDINFO_LATE=y
 CONFIG_CMD_CPU=y
 CONFIG_CMD_LICENSE=y
 CONFIG_CMD_BOOTZ=y
+CONFIG_CMD_BOOTEFI_HELLO=y
 # CONFIG_CMD_ELF is not set
 CONFIG_CMD_ASKENV=y
 CONFIG_CMD_GREPENV=y
@@ -43,6 +45,7 @@
 CONFIG_CMD_SNTP=y
 CONFIG_CMD_DNS=y
 CONFIG_CMD_LINK_LOCAL=y
+CONFIG_CMD_EFIDEBUG=y
 CONFIG_CMD_TIME=y
 CONFIG_CMD_TIMER=y
 CONFIG_CMD_SOUND=y
diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig
index 53c5bd8..18c6a47 100644
--- a/configs/sandbox_spl_defconfig
+++ b/configs/sandbox_spl_defconfig
@@ -28,6 +28,7 @@
 CONFIG_CMD_CPU=y
 CONFIG_CMD_LICENSE=y
 CONFIG_CMD_BOOTZ=y
+CONFIG_CMD_BOOTEFI_HELLO=y
 # CONFIG_CMD_ELF is not set
 CONFIG_CMD_ASKENV=y
 CONFIG_CMD_GREPENV=y
@@ -56,6 +57,7 @@
 CONFIG_CMD_DNS=y
 CONFIG_CMD_LINK_LOCAL=y
 CONFIG_CMD_BMP=y
+CONFIG_CMD_EFIDEBUG=y
 CONFIG_CMD_TIME=y
 CONFIG_CMD_TIMER=y
 CONFIG_CMD_SOUND=y
diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig
index 6d82365..c8f1780 100644
--- a/configs/stm32mp15_basic_defconfig
+++ b/configs/stm32mp15_basic_defconfig
@@ -21,10 +21,7 @@
 CONFIG_SPL_POWER_SUPPORT=y
 CONFIG_SYS_SPI_U_BOOT_OFFS=0x80000
 CONFIG_SYS_PROMPT="STM32MP> "
-# CONFIG_CMD_BOOTD is not set
 # CONFIG_CMD_ELF is not set
-# CONFIG_CMD_IMI is not set
-# CONFIG_CMD_XIMG is not set
 # CONFIG_CMD_EXPORTENV is not set
 # CONFIG_CMD_IMPORTENV is not set
 CONFIG_CMD_MEMINFO=y
diff --git a/configs/stm32mp15_dhcom_basic_defconfig b/configs/stm32mp15_dhcom_basic_defconfig
index 921dea2..683f15e 100644
--- a/configs/stm32mp15_dhcom_basic_defconfig
+++ b/configs/stm32mp15_dhcom_basic_defconfig
@@ -93,6 +93,7 @@
 CONFIG_SPL_SPI_FLASH_MTD=y
 CONFIG_DM_ETH=y
 CONFIG_DWC_ETH_QOS=y
+CONFIG_KS8851_MLL=y
 CONFIG_PHY=y
 CONFIG_PHY_STM32_USBPHYC=y
 CONFIG_PINCONF=y
diff --git a/configs/stm32mp15_optee_defconfig b/configs/stm32mp15_optee_defconfig
index 2986117..6c17bd9 100644
--- a/configs/stm32mp15_optee_defconfig
+++ b/configs/stm32mp15_optee_defconfig
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_STM32MP=y
+CONFIG_TFABOOT=y
 CONFIG_SYS_MALLOC_F_LEN=0x3000
 CONFIG_ENV_SECT_SIZE=0x40000
 CONFIG_ENV_OFFSET=0x280000
diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig
index 6928e9a..d22605f 100644
--- a/configs/stm32mp15_trusted_defconfig
+++ b/configs/stm32mp15_trusted_defconfig
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_STM32MP=y
+CONFIG_TFABOOT=y
 CONFIG_SYS_MALLOC_F_LEN=0x3000
 CONFIG_ENV_SECT_SIZE=0x40000
 CONFIG_ENV_OFFSET=0x280000
@@ -9,10 +10,7 @@
 CONFIG_FIT=y
 CONFIG_BOOTCOMMAND="run bootcmd_stm32mp"
 CONFIG_SYS_PROMPT="STM32MP> "
-# CONFIG_CMD_BOOTD is not set
 # CONFIG_CMD_ELF is not set
-# CONFIG_CMD_IMI is not set
-# CONFIG_CMD_XIMG is not set
 # CONFIG_CMD_EXPORTENV is not set
 # CONFIG_CMD_IMPORTENV is not set
 CONFIG_CMD_MEMINFO=y
diff --git a/configs/tools-only_defconfig b/configs/tools-only_defconfig
index 6ca50dc..2811b2c 100644
--- a/configs/tools-only_defconfig
+++ b/configs/tools-only_defconfig
@@ -26,3 +26,4 @@
 # CONFIG_VIRTIO_PCI is not set
 # CONFIG_VIRTIO_SANDBOX is not set
 # CONFIG_EFI_LOADER is not set
+# CONFIG_ACPIGEN is not set
diff --git a/doc/README.log b/doc/README.log
index 19856d4..1057981 100644
--- a/doc/README.log
+++ b/doc/README.log
@@ -147,7 +147,10 @@
 enabled or disabled independently:
 
    console - goes to stdout
+   syslog - broadcast RFC 3164 messages to syslog servers on UDP port 514
 
+The syslog driver sends the value of environmental variable 'log_hostname' as
+HOSTNAME if available.
 
 Log format
 ----------
diff --git a/doc/device-tree-bindings/gpio/intel,apl-gpio.txt b/doc/device-tree-bindings/gpio/intel,apl-gpio.txt
index cf0659b..8422ff6 100644
--- a/doc/device-tree-bindings/gpio/intel,apl-gpio.txt
+++ b/doc/device-tree-bindings/gpio/intel,apl-gpio.txt
@@ -47,7 +47,7 @@
 			reg = <0x50>;
 			compatible = "google,cr50";
 			u-boot,i2c-offset-len = <0>;
-			ready-gpio = <&gpio_n GPIO_28 GPIO_ACTIVE_LOW>;
+			ready-gpios = <&gpio_n GPIO_28 GPIO_ACTIVE_LOW>;
 		};
 	};
 
diff --git a/doc/device-tree-bindings/input/hid-over-i2c.txt b/doc/device-tree-bindings/input/hid-over-i2c.txt
new file mode 100644
index 0000000..c76bafa
--- /dev/null
+++ b/doc/device-tree-bindings/input/hid-over-i2c.txt
@@ -0,0 +1,44 @@
+* HID over I2C Device-Tree bindings
+
+HID over I2C provides support for various Human Interface Devices over the
+I2C bus. These devices can be for example touchpads, keyboards, touch screens
+or sensors.
+
+The specification has been written by Microsoft and is currently available here:
+http://msdn.microsoft.com/en-us/library/windows/hardware/hh852380.aspx
+
+If this binding is used, the kernel module i2c-hid will handle the communication
+with the device and the generic hid core layer will handle the protocol.
+
+Required properties:
+- compatible: must be "hid-over-i2c"
+- reg: i2c slave address
+- hid-descr-addr: HID descriptor address
+- interrupts: interrupt line
+
+Additional optional properties:
+
+Some devices may support additional optional properties to help with, e.g.,
+power sequencing. The following properties can be supported by one or more
+device-specific compatible properties, which should be used in addition to the
+"hid-over-i2c" string.
+
+- compatible:
+  * "wacom,w9013" (Wacom W9013 digitizer). Supports:
+    - vdd-supply (3.3V)
+    - vddl-supply (1.8V)
+    - post-power-on-delay-ms
+
+- vdd-supply: phandle of the regulator that provides the supply voltage.
+- post-power-on-delay-ms: time required by the device after enabling its regulators
+  or powering it on, before it is ready for communication.
+
+Example:
+
+	i2c-hid-dev@2c {
+		compatible = "hid-over-i2c";
+		reg = <0x2c>;
+		hid-descr-addr = <0x0020>;
+		interrupt-parent = <&gpx3>;
+		interrupts = <3 2>;
+	};
diff --git a/doc/device-tree-bindings/interrupt-controller/intel,acpi-gpe.txt b/doc/device-tree-bindings/interrupt-controller/intel,acpi-gpe.txt
index d9252bf..2fe02d8 100644
--- a/doc/device-tree-bindings/interrupt-controller/intel,acpi-gpe.txt
+++ b/doc/device-tree-bindings/interrupt-controller/intel,acpi-gpe.txt
@@ -25,6 +25,6 @@
 	tpm@50 {
 		reg = <0x50>;
 		compatible = "google,cr50";
-		ready-gpio = <&gpio_n 0x1c GPIO_ACTIVE_LOW>;
+		ready-gpios = <&gpio_n 0x1c GPIO_ACTIVE_LOW>;
 		interrupts-extended = <&acpi_gpe 0x3c 0>;
 	};
diff --git a/doc/device-tree-bindings/pci/x86-pci.txt b/doc/device-tree-bindings/pci/x86-pci.txt
index 3aa5bd9..95e370b 100644
--- a/doc/device-tree-bindings/pci/x86-pci.txt
+++ b/doc/device-tree-bindings/pci/x86-pci.txt
@@ -10,6 +10,17 @@
 	configuration in TPL/SPL to reduce code size and boot time, since these
 	phases only know about a small subset of PCI devices.
 
+For PCI devices the following optional property is available:
+
+- pci,no-autoconfig : Don't automatically configure this PCI device at all.
+	This is used when the device is statically configured and must maintain
+	this same config throughout the boot process. An example is a serial
+	UART being used to debug PCI configuration, since reconfiguring it stops
+	the UART from working until the driver is re-probed, and this can cause
+	output to be lost. This should not generally be used in production code,
+	although it is often harmless.
+
+
 Example:
 
 pci {
@@ -21,4 +32,16 @@
 		0x42000000 0x0 0xb0000000 0xb0000000 0 0x10000000
 		0x01000000 0x0 0x1000 0x1000 0 0xefff>;
 	u-boot,skip-auto-config-until-reloc;
+
+
+	serial: serial@18,2 {
+		reg = <0x0200c210 0 0 0 0>;
+		u-boot,dm-pre-reloc;
+		compatible = "intel,apl-ns16550";
+		early-regs = <0xde000000 0x20>;
+		reg-shift = <2>;
+		clock-frequency = <1843200>;
+		current-speed = <115200>;
+		pci,no-autoconfig;
+	};
 };
diff --git a/doc/driver-model/design.rst b/doc/driver-model/design.rst
index 5247ecc..635effc 100644
--- a/doc/driver-model/design.rst
+++ b/doc/driver-model/design.rst
@@ -579,7 +579,7 @@
 up) uclass::
 
    xhci_usb (UCLASS_USB)
-      eth (UCLASS_ETHERNET)
+      eth (UCLASS_ETH)
       camera (UCLASS_CAMERA)
       flash (UCLASS_FLASH_STORAGE)
 
@@ -683,11 +683,17 @@
 U-Boot it may be expensive to probe devices and we don't want to do it until
 they are needed, or perhaps until after relocation.
 
-Activation/probe
-^^^^^^^^^^^^^^^^
+Reading ofdata
+^^^^^^^^^^^^^^
 
-When a device needs to be used, U-Boot activates it, by following these
-steps (see device_probe()):
+Most devices have data in the device tree which they can read to find out the
+base address of hardware registers and parameters relating to driver
+operation. This is called 'ofdata' (Open-Firmware data).
+
+The device's_ofdata_to_platdata() implemnents allocation and reading of
+platdata. A parent's ofdata is always read before a child.
+
+The steps are:
 
    1. If priv_auto_alloc_size is non-zero, then the device-private space
    is allocated for the device and zeroed. It will be accessible as
@@ -713,32 +719,72 @@
    space. The controller can hold information about the USB state of each
    of its children.
 
+   5. If the driver provides an ofdata_to_platdata() method, then this is
+   called to convert the device tree data into platform data. This should
+   do various calls like dev_read_u32(dev, ...) to access the node and store
+   the resulting information into dev->platdata. After this point, the device
+   works the same way whether it was bound using a device tree node or
+   U_BOOT_DEVICE() structure. In either case, the platform data is now stored
+   in the platdata structure. Typically you will use the
+   platdata_auto_alloc_size feature to specify the size of the platform data
+   structure, and U-Boot will automatically allocate and zero it for you before
+   entry to ofdata_to_platdata(). But if not, you can allocate it yourself in
+   ofdata_to_platdata(). Note that it is preferable to do all the device tree
+   decoding in ofdata_to_platdata() rather than in probe(). (Apart from the
+   ugliness of mixing configuration and run-time data, one day it is possible
+   that U-Boot will cache platform data for devices which are regularly
+   de/activated).
+
+   5. The device is marked 'platdata valid'.
+
+Note that ofdata reading is always done (for a child and all its parents)
+before probing starts. Thus devices go through two distinct states when
+probing: reading platform data and actually touching the hardware to bring
+the device up.
+
+Having probing separate from ofdata-reading helps deal with of-platdata, where
+the probe() method is common to both DT/of-platdata operation, but the
+ofdata_to_platdata() method is implemented differently.
+
-   5. All parent devices are probed. It is not possible to activate a device
+Another case has come up where this separate is useful. Generation of ACPI
+tables uses the of-platdata but does not want to probe the device. Probing
+would cause U-Boot to violate one of its design principles, viz that it
+should only probe devices that are used. For ACPI we want to generate a
+table for each device, even if U-Boot does not use it. In fact it may not
+even be possible to probe the device - e.g. an SD card which is not
+present will cause an error on probe, yet we still must tell Linux about
+the SD card connector in case it is used while Linux is running.
+
+It is important that the ofdata_to_platdata() method does not actually probe
+the device itself. However there are cases where other devices must be probed
+in the ofdata_to_platdata() method. An example is where a device requires a
+GPIO for it to operate. To select a GPIO obviously requires that the GPIO
+device is probed. This is OK when used by common, core devices such as GPIO,
+clock, interrupts, reset and the like.
+
+If your device relies on its parent setting up a suitable address space, so
+that dev_read_addr() works correctly, then make sure that the parent device
+has its setup code in ofdata_to_platdata(). If it has it in the probe method,
+then you cannot call dev_read_addr() from the child device's
+ofdata_to_platdata() method. Move it to probe() instead. Buses like PCI can
+fall afoul of this rule.
+
+Activation/probe
+^^^^^^^^^^^^^^^^
+
+When a device needs to be used, U-Boot activates it, by first reading ofdata
+as above and then following these steps (see device_probe()):
+
+   1. All parent devices are probed. It is not possible to activate a device
    unless its predecessors (all the way up to the root device) are activated.
    This means (for example) that an I2C driver will require that its bus
    be activated.
 
-   6. The device's sequence number is assigned, either the requested one
+   2. The device's sequence number is assigned, either the requested one
    (assuming no conflicts) or the next available one if there is a conflict
    or nothing particular is requested.
 
-   7. If the driver provides an ofdata_to_platdata() method, then this is
-   called to convert the device tree data into platform data. This should
-   do various calls like fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), ...)
-   to access the node and store the resulting information into dev->platdata.
-   After this point, the device works the same way whether it was bound
-   using a device tree node or U_BOOT_DEVICE() structure. In either case,
-   the platform data is now stored in the platdata structure. Typically you
-   will use the platdata_auto_alloc_size feature to specify the size of the
-   platform data structure, and U-Boot will automatically allocate and zero
-   it for you before entry to ofdata_to_platdata(). But if not, you can
-   allocate it yourself in ofdata_to_platdata(). Note that it is preferable
-   to do all the device tree decoding in ofdata_to_platdata() rather than
-   in probe(). (Apart from the ugliness of mixing configuration and run-time
-   data, one day it is possible that U-Boot will cache platform data for
-   devices which are regularly de/activated).
-
-   8. The device's probe() method is called. This should do anything that
+   4. The device's probe() method is called. This should do anything that
    is required by the device to get it going. This could include checking
    that the hardware is actually present, setting up clocks for the
    hardware and setting up hardware registers to initial values. The code
@@ -753,7 +799,7 @@
    allocate the priv space here yourself. The same applies also to
    platdata_auto_alloc_size. Remember to free them in the remove() method.
 
-   9. The device is marked 'activated'
+   5. The device is marked 'activated'
 
    10. The uclass's post_probe() method is called, if one exists. This may
    cause the uclass to do some housekeeping to record the device as
diff --git a/doc/driver-model/pci-info.rst b/doc/driver-model/pci-info.rst
index 3c1b1ad..8b9faa1 100644
--- a/doc/driver-model/pci-info.rst
+++ b/doc/driver-model/pci-info.rst
@@ -12,10 +12,10 @@
 tree file will point to the correct device::
 
 	aliases {
-		pci0 = &pci;
+		pci0 = &pcic;
 	};
 
-	pci: pci-controller {
+	pcic: pci@0 {
 		compatible = "sandbox,pci";
 		...
 	};
@@ -138,7 +138,7 @@
 
 When this bus is scanned we will end up with something like this::
 
-   `- * pci-controller @ 05c660c8, 0
+   `- * pci@0 @ 05c660c8, 0
     `-   pci@1f,0 @ 05c661c8, 63488
    `-   emul@1f,0 @ 05c662c8
 
@@ -152,7 +152,7 @@
 
 .. code-block:: none
 
-	pci1: pci-controller1 {
+	pci1: pci@1 {
 		compatible = "sandbox,pci";
 		...
 		sandbox,dev-info = <0x08 0x00 0x1234 0x5678
@@ -166,6 +166,6 @@
 
 When this bus is scanned we will end up with something like this::
 
- pci        [ + ]   pci_sandbo  |-- pci-controller1
+ pci        [ + ]   pci_sandbo  |-- pci1
  pci_emul   [   ]   sandbox_sw  |   |-- sandbox_swap_case_emul
  pci_emul   [   ]   sandbox_sw  |   `-- sandbox_swap_case_emul
diff --git a/drivers/clk/altera/clk-arria10.c b/drivers/clk/altera/clk-arria10.c
index b7eed94..694a942 100644
--- a/drivers/clk/altera/clk-arria10.c
+++ b/drivers/clk/altera/clk-arria10.c
@@ -258,7 +258,7 @@
 			continue;
 
 		if (pre_reloc_only &&
-		    !dm_ofnode_pre_reloc(offset_to_ofnode(offset)))
+		    !ofnode_pre_reloc(offset_to_ofnode(offset)))
 			continue;
 
 		ret = device_bind_driver_to_node(dev, "clk-a10", name,
diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index 6b55ec5..f580844 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -61,7 +61,7 @@
 	     offset > 0;
 	     offset = fdt_next_subnode(fdt, offset)) {
 		if (pre_reloc_only &&
-		    !dm_ofnode_pre_reloc(offset_to_ofnode(offset)))
+		    !ofnode_pre_reloc(offset_to_ofnode(offset)))
 			continue;
 		/*
 		 * If this node has "compatible" property, this is not
diff --git a/drivers/clk/clk_stm32mp1.c b/drivers/clk/clk_stm32mp1.c
index 52bd8e9..50df842 100644
--- a/drivers/clk/clk_stm32mp1.c
+++ b/drivers/clk/clk_stm32mp1.c
@@ -19,7 +19,7 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#ifndef CONFIG_STM32MP1_TRUSTED
+#ifndef CONFIG_TFABOOT
 #if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
 /* activate clock tree initialization in the driver */
 #define STM32MP1_CLOCK_TREE_INIT
diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig
index 3b95b53..a3b0399 100644
--- a/drivers/core/Kconfig
+++ b/drivers/core/Kconfig
@@ -261,4 +261,13 @@
 	bool
 	default y if !OF_LIVE
 
+config ACPIGEN
+	bool "Support ACPI table generation in driver model"
+	default y if SANDBOX || GENERATE_ACPI_TABLE
+	help
+	  This option enables generation of ACPI tables using driver-model
+	  devices. It adds a new operation struct to each driver, to support
+	  things like generating device-specific tables and returning the ACPI
+	  name of a device.
+
 endmenu
diff --git a/drivers/core/Makefile b/drivers/core/Makefile
index bce7467..c707026 100644
--- a/drivers/core/Makefile
+++ b/drivers/core/Makefile
@@ -3,6 +3,7 @@
 # Copyright (c) 2013 Google, Inc
 
 obj-y	+= device.o fdtaddr.o lists.o root.o uclass.o util.o
+obj-$(CONFIG_$(SPL_TPL_)ACPIGEN) += acpi.o
 obj-$(CONFIG_DEVRES) += devres.o
 obj-$(CONFIG_$(SPL_)DM_DEVICE_REMOVE)	+= device-remove.o
 obj-$(CONFIG_$(SPL_)SIMPLE_BUS)	+= simple-bus.o
diff --git a/drivers/core/acpi.c b/drivers/core/acpi.c
new file mode 100644
index 0000000..ba50d68
--- /dev/null
+++ b/drivers/core/acpi.c
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Core driver model support for ACPI table generation
+ *
+ * Copyright 2019 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#define LOG_CATEOGRY	LOGC_ACPI
+
+#include <common.h>
+#include <dm.h>
+#include <dm/acpi.h>
+#include <dm/root.h>
+
+int acpi_copy_name(char *out_name, const char *name)
+{
+	strncpy(out_name, name, ACPI_NAME_LEN);
+	out_name[ACPI_NAME_LEN] = '\0';
+
+	return 0;
+}
+
+int acpi_get_name(const struct udevice *dev, char *out_name)
+{
+	struct acpi_ops *aops;
+
+	aops = device_get_acpi_ops(dev);
+	if (aops && aops->get_name)
+		return aops->get_name(dev, out_name);
+
+	return -ENOSYS;
+}
diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c
index ff5b28c..efdb0f2 100644
--- a/drivers/core/device-remove.c
+++ b/drivers/core/device-remove.c
@@ -10,6 +10,7 @@
 
 #include <common.h>
 #include <errno.h>
+#include <log.h>
 #include <malloc.h>
 #include <dm/device.h>
 #include <dm/device-internal.h>
@@ -30,11 +31,14 @@
 			continue;
 
 		ret = device_unbind(pos);
-		if (ret && !saved_ret)
+		if (ret && !saved_ret) {
+			log_warning("device '%s' failed to unbind\n",
+				    pos->name);
 			saved_ret = ret;
+		}
 	}
 
-	return saved_ret;
+	return log_ret(saved_ret);
 }
 
 int device_chld_remove(struct udevice *dev, struct driver *drv,
@@ -63,13 +67,13 @@
 	int ret;
 
 	if (!dev)
-		return -EINVAL;
+		return log_msg_ret("dev", -EINVAL);
 
 	if (dev->flags & DM_FLAG_ACTIVATED)
-		return -EINVAL;
+		return log_msg_ret("active", -EINVAL);
 
 	if (!(dev->flags & DM_FLAG_BOUND))
-		return -EINVAL;
+		return log_msg_ret("not-bound", -EINVAL);
 
 	drv = dev->driver;
 	assert(drv);
@@ -77,12 +81,12 @@
 	if (drv->unbind) {
 		ret = drv->unbind(dev);
 		if (ret)
-			return ret;
+			return log_msg_ret("unbind", ret);
 	}
 
 	ret = device_chld_unbind(dev, NULL);
 	if (ret)
-		return ret;
+		return log_msg_ret("child unbind", ret);
 
 	if (dev->flags & DM_FLAG_ALLOC_PDATA) {
 		free(dev->platdata);
@@ -98,7 +102,7 @@
 	}
 	ret = uclass_unbind_device(dev);
 	if (ret)
-		return ret;
+		return log_msg_ret("uc", ret);
 
 	if (dev->parent)
 		list_del(&dev->sibling_node);
@@ -194,7 +198,8 @@
 		}
 	}
 
-	if (!(drv->flags &
+	if (!(flags & DM_REMOVE_NO_PD) &&
+	    !(drv->flags &
 	      (DM_FLAG_DEFAULT_PD_CTRL_OFF | DM_FLAG_REMOVE_WITH_PD_ON)) &&
 	    dev != gd->cur_serial_dev)
 		dev_power_domain_off(dev);
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 89ea820..0157bb1 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -143,11 +143,9 @@
 				goto fail_alloc3;
 			}
 		}
-	}
-
-	/* put dev into parent's successor list */
-	if (parent)
+		/* put dev into parent's successor list */
 		list_add_tail(&dev->sibling_node, &parent->child_head);
+	}
 
 	ret = uclass_bind_device(dev);
 	if (ret)
@@ -323,6 +321,22 @@
 	if (dev->flags & DM_FLAG_PLATDATA_VALID)
 		return 0;
 
+	/* Ensure all parents have ofdata */
+	if (dev->parent) {
+		ret = device_ofdata_to_platdata(dev->parent);
+		if (ret)
+			goto fail;
+
+		/*
+		 * The device might have already been probed during
+		 * the call to device_probe() on its parent device
+		 * (e.g. PCI bridge devices). Test the flags again
+		 * so that we don't mess up the device.
+		 */
+		if (dev->flags & DM_FLAG_PLATDATA_VALID)
+			return 0;
+	}
+
 	drv = dev->driver;
 	assert(drv);
 
diff --git a/drivers/core/lists.c b/drivers/core/lists.c
index 68204c3..c7db14e 100644
--- a/drivers/core/lists.c
+++ b/drivers/core/lists.c
@@ -175,7 +175,7 @@
 			continue;
 
 		if (pre_reloc_only) {
-			if (!dm_ofnode_pre_reloc(node) &&
+			if (!ofnode_pre_reloc(node) &&
 			    !(entry->flags & DM_FLAG_PRE_RELOC)) {
 				log_debug("Skipping device pre-relocation\n");
 				return 0;
diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c
index acd745c..c54baa1 100644
--- a/drivers/core/of_access.c
+++ b/drivers/core/of_access.c
@@ -449,21 +449,7 @@
 
 int of_read_u32(const struct device_node *np, const char *propname, u32 *outp)
 {
-	const __be32 *val;
-
-	debug("%s: %s: ", __func__, propname);
-	if (!np)
-		return -EINVAL;
-	val = of_find_property_value_of_size(np, propname, sizeof(*outp));
-	if (IS_ERR(val)) {
-		debug("(not found)\n");
-		return PTR_ERR(val);
-	}
-
-	*outp = be32_to_cpup(val);
-	debug("%#x (%d)\n", *outp, *outp);
-
-	return 0;
+	return of_read_u32_index(np, propname, 0, outp);
 }
 
 int of_read_u32_array(const struct device_node *np, const char *propname,
@@ -485,6 +471,28 @@
 	return 0;
 }
 
+int of_read_u32_index(const struct device_node *np, const char *propname,
+		      int index, u32 *outp)
+{
+	const __be32 *val;
+
+	debug("%s: %s: ", __func__, propname);
+	if (!np)
+		return -EINVAL;
+
+	val = of_find_property_value_of_size(np, propname,
+					     sizeof(*outp) * (index + 1));
+	if (IS_ERR(val)) {
+		debug("(not found)\n");
+		return PTR_ERR(val);
+	}
+
+	*outp = be32_to_cpup(val + index);
+	debug("%#x (%d)\n", *outp, *outp);
+
+	return 0;
+}
+
 int of_read_u64(const struct device_node *np, const char *propname, u64 *outp)
 {
 	const __be64 *val;
@@ -577,7 +585,7 @@
 {
 	const __be32 *list, *list_end;
 	int rc = 0, cur_index = 0;
-	uint32_t count = 0;
+	uint32_t count;
 	struct device_node *node = NULL;
 	phandle phandle;
 	int size;
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
index 96a5dd2..b0be7cb 100644
--- a/drivers/core/ofnode.c
+++ b/drivers/core/ofnode.c
@@ -18,32 +18,53 @@
 
 int ofnode_read_u32(ofnode node, const char *propname, u32 *outp)
 {
+	return ofnode_read_u32_index(node, propname, 0, outp);
+}
+
+u32 ofnode_read_u32_default(ofnode node, const char *propname, u32 def)
+{
+	assert(ofnode_valid(node));
+	ofnode_read_u32_index(node, propname, 0, &def);
+
+	return def;
+}
+
+int ofnode_read_u32_index(ofnode node, const char *propname, int index,
+			  u32 *outp)
+{
+	const fdt32_t *cell;
+	int len;
+
 	assert(ofnode_valid(node));
 	debug("%s: %s: ", __func__, propname);
 
-	if (ofnode_is_np(node)) {
-		return of_read_u32(ofnode_to_np(node), propname, outp);
-	} else {
-		const fdt32_t *cell;
-		int len;
+	if (ofnode_is_np(node))
+		return of_read_u32_index(ofnode_to_np(node), propname, index,
+					 outp);
 
-		cell = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node),
-				   propname, &len);
-		if (!cell || len < sizeof(int)) {
-			debug("(not found)\n");
-			return -EINVAL;
-		}
-		*outp = fdt32_to_cpu(cell[0]);
+	cell = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), propname,
+			   &len);
+	if (!cell) {
+		debug("(not found)\n");
+		return -EINVAL;
 	}
+
+	if (len < (sizeof(int) * (index + 1))) {
+		debug("(not large enough)\n");
+		return -EOVERFLOW;
+	}
+
+	*outp = fdt32_to_cpu(cell[index]);
 	debug("%#x (%d)\n", *outp, *outp);
 
 	return 0;
 }
 
-u32 ofnode_read_u32_default(ofnode node, const char *propname, u32 def)
+u32 ofnode_read_u32_index_default(ofnode node, const char *propname, int index,
+				  u32 def)
 {
 	assert(ofnode_valid(node));
-	ofnode_read_u32(node, propname, &def);
+	ofnode_read_u32_index(node, propname, index, &def);
 
 	return def;
 }
diff --git a/drivers/core/read.c b/drivers/core/read.c
index 1f999b1..ce78f09 100644
--- a/drivers/core/read.c
+++ b/drivers/core/read.c
@@ -22,6 +22,19 @@
 	return ofnode_read_u32_default(dev_ofnode(dev), propname, def);
 }
 
+int dev_read_u32_index(struct udevice *dev, const char *propname, int index,
+		       u32 *outp)
+{
+	return ofnode_read_u32_index(dev_ofnode(dev), propname, index, outp);
+}
+
+u32 dev_read_u32_index_default(struct udevice *dev, const char *propname,
+			       int index, u32 def)
+{
+	return ofnode_read_u32_index_default(dev_ofnode(dev), propname, index,
+					     def);
+}
+
 int dev_read_s32(const struct udevice *dev, const char *propname, s32 *outp)
 {
 	return ofnode_read_u32(dev_ofnode(dev), propname, (u32 *)outp);
diff --git a/drivers/core/root.c b/drivers/core/root.c
index e856438..14df16c 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -203,15 +203,6 @@
 	int ret = 0, err;
 
 	for (np = node_parent->child; np; np = np->sibling) {
-		/* "chosen" node isn't a device itself but may contain some: */
-		if (!strcmp(np->name, "chosen")) {
-			pr_debug("parsing subnodes of \"chosen\"\n");
-
-			err = dm_scan_fdt_live(parent, np, pre_reloc_only);
-			if (err && !ret)
-				ret = err;
-			continue;
-		}
 
 		if (!of_device_is_available(np)) {
 			pr_debug("   - ignoring disabled device\n");
@@ -256,21 +247,6 @@
 	     offset = fdt_next_subnode(blob, offset)) {
 		const char *node_name = fdt_get_name(blob, offset, NULL);
 
-		/*
-		 * The "chosen" and "firmware" nodes aren't devices
-		 * themselves but may contain some:
-		 */
-		if (!strcmp(node_name, "chosen") ||
-		    !strcmp(node_name, "firmware")) {
-			pr_debug("parsing subnodes of \"%s\"\n", node_name);
-
-			err = dm_scan_fdt_node(parent, blob, offset,
-					       pre_reloc_only);
-			if (err && !ret)
-				ret = err;
-			continue;
-		}
-
 		if (!fdtdec_get_is_enabled(blob, offset)) {
 			pr_debug("   - ignoring disabled device\n");
 			continue;
@@ -315,7 +291,8 @@
 	return dm_scan_fdt_node(gd->dm_root, blob, 0, pre_reloc_only);
 }
 
-static int dm_scan_fdt_ofnode_path(const char *path, bool pre_reloc_only)
+static int dm_scan_fdt_ofnode_path(const void *blob, const char *path,
+				   bool pre_reloc_only)
 {
 	ofnode node;
 
@@ -327,13 +304,18 @@
 	if (of_live_active())
 		return dm_scan_fdt_live(gd->dm_root, node.np, pre_reloc_only);
 #endif
-	return dm_scan_fdt_node(gd->dm_root, gd->fdt_blob, node.of_offset,
+	return dm_scan_fdt_node(gd->dm_root, blob, node.of_offset,
 				pre_reloc_only);
 }
 
 int dm_extended_scan_fdt(const void *blob, bool pre_reloc_only)
 {
-	int ret;
+	int ret, i;
+	const char * const nodes[] = {
+		"/chosen",
+		"/clocks",
+		"/firmware"
+	};
 
 	ret = dm_scan_fdt(blob, pre_reloc_only);
 	if (ret) {
@@ -341,16 +323,16 @@
 		return ret;
 	}
 
-	ret = dm_scan_fdt_ofnode_path("/clocks", pre_reloc_only);
-	if (ret) {
-		debug("scan for /clocks failed: %d\n", ret);
-		return ret;
+	/* Some nodes aren't devices themselves but may contain some */
+	for (i = 0; i < ARRAY_SIZE(nodes); i++) {
+		ret = dm_scan_fdt_ofnode_path(blob, nodes[i], pre_reloc_only);
+		if (ret) {
+			debug("dm_scan_fdt() scan for %s failed: %d\n",
+			      nodes[i], ret);
+			return ret;
+		}
 	}
 
-	ret = dm_scan_fdt_ofnode_path("/firmware", pre_reloc_only);
-	if (ret)
-		debug("scan for /firmware failed: %d\n", ret);
-
 	return ret;
 }
 #endif
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index 58b19a4..6849302 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -118,12 +118,12 @@
 	while (!list_empty(&uc->dev_head)) {
 		dev = list_first_entry(&uc->dev_head, struct udevice,
 				       uclass_node);
-		ret = device_remove(dev, DM_REMOVE_NORMAL);
+		ret = device_remove(dev, DM_REMOVE_NORMAL | DM_REMOVE_NO_PD);
 		if (ret)
-			return ret;
+			return log_msg_ret("remove", ret);
 		ret = device_unbind(dev);
 		if (ret)
-			return ret;
+			return log_msg_ret("unbind", ret);
 	}
 
 	uc_drv = uc->uc_drv;
diff --git a/drivers/core/util.c b/drivers/core/util.c
index 69f8375..25b0d76 100644
--- a/drivers/core/util.c
+++ b/drivers/core/util.c
@@ -33,34 +33,6 @@
 	return count;
 }
 
-#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
-bool dm_ofnode_pre_reloc(ofnode node)
-{
-#if defined(CONFIG_SPL_BUILD) || defined(CONFIG_TPL_BUILD)
-	/* for SPL and TPL the remaining nodes after the fdtgrep 1st pass
-	 * had property dm-pre-reloc or u-boot,dm-spl/tpl.
-	 * They are removed in final dtb (fdtgrep 2nd pass)
-	 */
-	return true;
-#else
-	if (ofnode_read_bool(node, "u-boot,dm-pre-reloc"))
-		return true;
-	if (ofnode_read_bool(node, "u-boot,dm-pre-proper"))
-		return true;
-
-	/*
-	 * In regular builds individual spl and tpl handling both
-	 * count as handled pre-relocation for later second init.
-	 */
-	if (ofnode_read_bool(node, "u-boot,dm-spl") ||
-	    ofnode_read_bool(node, "u-boot,dm-tpl"))
-		return true;
-
-	return false;
-#endif
-}
-#endif
-
 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
 int pci_get_devfn(struct udevice *dev)
 {
diff --git a/drivers/cpu/cpu_sandbox.c b/drivers/cpu/cpu_sandbox.c
index ff87e8a..05b384f 100644
--- a/drivers/cpu/cpu_sandbox.c
+++ b/drivers/cpu/cpu_sandbox.c
@@ -19,6 +19,7 @@
 {
 	info->cpu_freq = 42 * 42 * 42 * 42 * 42;
 	info->features = 0x42424242;
+	info->address_width = IS_ENABLED(CONFIG_PHYS_64BIT) ? 64 : 32;
 
 	return 0;
 }
diff --git a/drivers/misc/p2sb_emul.c b/drivers/misc/p2sb_emul.c
index a6ee9a2..02f7a7e 100644
--- a/drivers/misc/p2sb_emul.c
+++ b/drivers/misc/p2sb_emul.c
@@ -215,7 +215,7 @@
 					 void **ptrp)
 {
 	struct p2sb_emul_priv *priv = dev_get_priv(dev);
-	struct udevice *child;
+	struct udevice *child = NULL;  /* Silence compiler warning */
 	unsigned int offset;
 	int barnum;
 	int ret;
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
index 0564beb..63f2086 100644
--- a/drivers/net/dwc_eth_qos.c
+++ b/drivers/net/dwc_eth_qos.c
@@ -306,6 +306,8 @@
 	struct clk clk_slave_bus;
 	struct mii_dev *mii;
 	struct phy_device *phy;
+	int phyaddr;
+	u32 max_speed;
 	void *descs;
 	struct eqos_desc *tx_descs;
 	struct eqos_desc *rx_descs;
@@ -694,6 +696,29 @@
 
 static int eqos_start_resets_stm32(struct udevice *dev)
 {
+	struct eqos_priv *eqos = dev_get_priv(dev);
+	int ret;
+
+	debug("%s(dev=%p):\n", __func__, dev);
+	if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) {
+		ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 1);
+		if (ret < 0) {
+			pr_err("dm_gpio_set_value(phy_reset, assert) failed: %d",
+			       ret);
+			return ret;
+		}
+
+		udelay(2);
+
+		ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 0);
+		if (ret < 0) {
+			pr_err("dm_gpio_set_value(phy_reset, deassert) failed: %d",
+			       ret);
+			return ret;
+		}
+	}
+	debug("%s: OK\n", __func__);
+
 	return 0;
 }
 
@@ -709,6 +734,18 @@
 
 static int eqos_stop_resets_stm32(struct udevice *dev)
 {
+	struct eqos_priv *eqos = dev_get_priv(dev);
+	int ret;
+
+	if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) {
+		ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 1);
+		if (ret < 0) {
+			pr_err("dm_gpio_set_value(phy_reset, assert) failed: %d",
+			       ret);
+			return ret;
+		}
+	}
+
 	return 0;
 }
 
@@ -1046,12 +1083,21 @@
 	 * don't need to reconnect/reconfigure again
 	 */
 	if (!eqos->phy) {
-		eqos->phy = phy_connect(eqos->mii, -1, dev,
+		eqos->phy = phy_connect(eqos->mii, eqos->phyaddr, dev,
 					eqos->config->interface(dev));
 		if (!eqos->phy) {
 			pr_err("phy_connect() failed");
 			goto err_stop_resets;
 		}
+
+		if (eqos->max_speed) {
+			ret = phy_set_supported(eqos->phy, eqos->max_speed);
+			if (ret) {
+				pr_err("phy_set_supported() failed: %d", ret);
+				goto err_shutdown_phy;
+			}
+		}
+
 		ret = phy_config(eqos->phy);
 		if (ret < 0) {
 			pr_err("phy_config() failed: %d", ret);
@@ -1604,6 +1650,7 @@
 	struct eqos_priv *eqos = dev_get_priv(dev);
 	int ret;
 	phy_interface_t interface;
+	struct ofnode_phandle_args phandle_args;
 
 	debug("%s(dev=%p):\n", __func__, dev);
 
@@ -1618,6 +1665,8 @@
 	if (ret)
 		return -EINVAL;
 
+	eqos->max_speed = dev_read_u32_default(dev, "max-speed", 0);
+
 	ret = clk_get_by_name(dev, "stmmaceth", &eqos->clk_master_bus);
 	if (ret) {
 		pr_err("clk_get_by_name(master_bus) failed: %d", ret);
@@ -1641,6 +1690,24 @@
 	if (ret)
 		pr_warn("No phy clock provided %d", ret);
 
+	eqos->phyaddr = -1;
+	ret = dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0,
+					 &phandle_args);
+	if (!ret) {
+		/* search "reset-gpios" in phy node */
+		ret = gpio_request_by_name_nodev(phandle_args.node,
+						 "reset-gpios", 0,
+						 &eqos->phy_reset_gpio,
+						 GPIOD_IS_OUT |
+						 GPIOD_IS_OUT_ACTIVE);
+		if (ret)
+			pr_warn("gpio_request_by_name(phy reset) not provided %d",
+				ret);
+
+		eqos->phyaddr = ofnode_read_u32_default(phandle_args.node,
+							"reg", -1);
+	}
+
 	debug("%s: OK\n", __func__);
 	return 0;
 
@@ -1704,6 +1771,9 @@
 	if (clk_valid(&eqos->clk_ck))
 		clk_free(&eqos->clk_ck);
 
+	if (dm_gpio_is_valid(&eqos->phy_reset_gpio))
+		dm_gpio_free(dev, &eqos->phy_reset_gpio);
+
 	debug("%s: OK\n", __func__);
 	return 0;
 }
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index e2882e3..d2e10d6 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -536,6 +536,8 @@
 		int ret;
 
 		debug("%s: device %s\n", __func__, dev->name);
+		if (dev_read_bool(dev, "pci,no-autoconfig"))
+			continue;
 		ret = dm_pciauto_config_device(dev);
 		if (ret < 0)
 			return ret;
@@ -1211,7 +1213,14 @@
 
 	bar = PCI_BASE_ADDRESS_0 + barnum * 4;
 	dm_pci_read_config32(dev, bar, &addr);
-	if (addr & PCI_BASE_ADDRESS_SPACE_IO)
+
+	/*
+	 * If we get an invalid address, return this so that comparisons with
+	 * FDT_ADDR_T_NONE work correctly
+	 */
+	if (addr == 0xffffffff)
+		return addr;
+	else if (addr & PCI_BASE_ADDRESS_SPACE_IO)
 		return addr & PCI_BASE_ADDRESS_IO_MASK;
 	else
 		return addr & PCI_BASE_ADDRESS_MEM_MASK;
diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c
index 90f224b..6b17f18 100644
--- a/drivers/pci/pci_rom.c
+++ b/drivers/pci/pci_rom.c
@@ -33,12 +33,10 @@
 #include <vbe.h>
 #include <video.h>
 #include <video_fb.h>
+#include <acpi/acpi_s3.h>
 #include <linux/screen_info.h>
 
-#ifdef CONFIG_X86
-#include <acpi_s3.h>
 DECLARE_GLOBAL_DATA_PTR;
-#endif
 
 __weak bool board_should_run_oprom(struct udevice *dev)
 {
diff --git a/drivers/power/acpi_pmc/acpi-pmc-uclass.c b/drivers/power/acpi_pmc/acpi-pmc-uclass.c
index d43de87..1c79f83 100644
--- a/drivers/power/acpi_pmc/acpi-pmc-uclass.c
+++ b/drivers/power/acpi_pmc/acpi-pmc-uclass.c
@@ -6,9 +6,9 @@
 #define LOG_CATEGORY UCLASS_ACPI_PMC
 
 #include <common.h>
-#include <acpi_s3.h>
 #include <dm.h>
 #include <log.h>
+#include <acpi/acpi_s3.h>
 #ifdef CONFIG_X86
 #include <asm/intel_pinctrl.h>
 #endif
diff --git a/drivers/ram/stm32mp1/stm32mp1_ram.c b/drivers/ram/stm32mp1/stm32mp1_ram.c
index b1e593f..7b1adc5 100644
--- a/drivers/ram/stm32mp1/stm32mp1_ram.c
+++ b/drivers/ram/stm32mp1/stm32mp1_ram.c
@@ -177,7 +177,7 @@
 
 	priv->info.base = STM32_DDR_BASE;
 
-#if !defined(CONFIG_STM32MP1_TRUSTED) && \
+#if !defined(CONFIG_TFABOOT) && \
 	(!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD))
 	priv->info.size = 0;
 	return stm32mp1_ddr_setup(dev);
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index a2f1b35..6415d2e 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -476,6 +476,8 @@
 	info->reg_width = plat->reg_width;
 	info->reg_shift = plat->reg_shift;
 	info->reg_offset = plat->reg_offset;
+	info->clock = plat->clock;
+
 	return 0;
 }
 
diff --git a/drivers/serial/sandbox.c b/drivers/serial/sandbox.c
index 1af5cc1..545ff3f 100644
--- a/drivers/serial/sandbox.c
+++ b/drivers/serial/sandbox.c
@@ -198,6 +198,7 @@
 		.reg_width = 1,
 		.reg_offset = 0,
 		.reg_shift = 0,
+		.clock = SERIAL_DEFAULT_CLOCK,
 	};
 
 	if (!serial_info)
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index 30f9b8c..7703c67 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -162,6 +162,7 @@
 #if CONFIG_IS_ENABLED(SERIAL_PRESENT)
 	serial_find_console_or_panic();
 	gd->flags |= GD_FLG_SERIAL_READY;
+	serial_setbrg();
 #endif
 
 	return 0;
diff --git a/drivers/sysreset/sysreset_x86.c b/drivers/sysreset/sysreset_x86.c
index 8e2d1ea..bc91143 100644
--- a/drivers/sysreset/sysreset_x86.c
+++ b/drivers/sysreset/sysreset_x86.c
@@ -6,11 +6,11 @@
  */
 
 #include <common.h>
-#include <acpi_s3.h>
 #include <dm.h>
 #include <efi_loader.h>
 #include <pch.h>
 #include <sysreset.h>
+#include <acpi/acpi_s3.h>
 #include <asm/io.h>
 #include <asm/processor.h>
 
diff --git a/drivers/tpm/cr50_i2c.c b/drivers/tpm/cr50_i2c.c
index b904a7d..b67051a 100644
--- a/drivers/tpm/cr50_i2c.c
+++ b/drivers/tpm/cr50_i2c.c
@@ -34,6 +34,15 @@
 	CR50_MAX_BUF_SIZE = 63,
 };
 
+/**
+ * struct cr50_priv - Private driver data
+ *
+ * @ready_gpio: GPIO to use to check if the TPM is ready
+ * @irq: IRQ to use check if the TPM is ready (has priority over @ready_gpio)
+ * @locality: Currenttly claimed locality (-1 if none)
+ * @vendor: vendor: Vendor ID for TPM
+ * @use_irq: true to use @irq, false to use @ready if available
+ */
 struct cr50_priv {
 	struct gpio_desc ready_gpio;
 	struct irq irq;
@@ -206,7 +215,7 @@
 		cr50_i2c_write(dev, addr, &buf, 1);
 	}
 
-	priv->locality = 0;
+	priv->locality = -1;
 
 	return 0;
 }
@@ -499,6 +508,7 @@
 static int claim_locality(struct udevice *dev, int loc)
 {
 	const u8 mask = TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY;
+	struct cr50_priv *priv = dev_get_priv(dev);
 	u8 access;
 	int ret;
 
@@ -525,6 +535,7 @@
 		return -EPERM;
 	}
 	log_info("Claimed locality %d\n", loc);
+	priv->locality = loc;
 
 	return 0;
 }
@@ -559,7 +570,11 @@
 
 static int cr50_i2c_cleanup(struct udevice *dev)
 {
-	release_locality(dev, 1);
+	struct cr50_priv *priv = dev_get_priv(dev);
+
+	printf("%s: cleanup %d\n", __func__, priv->locality);
+	if (priv->locality != -1)
+		release_locality(dev, 1);
 
 	return 0;
 }
@@ -592,7 +607,7 @@
 		priv->irq = irq;
 		priv->use_irq = true;
 	} else {
-		ret = gpio_request_by_name(dev, "ready-gpio", 0,
+		ret = gpio_request_by_name(dev, "ready-gpios", 0,
 					   &priv->ready_gpio, GPIOD_IS_IN);
 		if (ret) {
 			log_warning("Cr50 does not have an ready GPIO/interrupt (err=%d)\n",
@@ -631,6 +646,7 @@
 		return log_msg_ret("vendor-id", -EXDEV);
 	}
 	priv->vendor = vendor;
+	priv->locality = -1;
 
 	return 0;
 }
@@ -655,5 +671,7 @@
 	.ops    = &cr50_i2c_ops,
 	.ofdata_to_platdata	= cr50_i2c_ofdata_to_platdata,
 	.probe	= cr50_i2c_probe,
+	.remove	= cr50_i2c_cleanup,
 	.priv_auto_alloc_size = sizeof(struct cr50_priv),
+	.flags		= DM_FLAG_OS_PREPARE,
 };
diff --git a/drivers/tpm/tpm-uclass.c b/drivers/tpm/tpm-uclass.c
index 1b11c93..71d5807 100644
--- a/drivers/tpm/tpm-uclass.c
+++ b/drivers/tpm/tpm-uclass.c
@@ -72,7 +72,7 @@
 	struct tpm_ops *ops = tpm_get_ops(dev);
 	ulong start, stop;
 	uint count, ordinal;
-	int ret, ret2;
+	int ret, ret2 = 0;
 
 	if (ops->xfer)
 		return ops->xfer(dev, sendbuf, send_size, recvbuf, recv_size);
@@ -120,9 +120,16 @@
 		}
 	} while (ret);
 
-	ret2 = ops->cleanup ? ops->cleanup(dev) : 0;
+	if (ret) {
+		if (ops->cleanup) {
+			ret2 = ops->cleanup(dev);
+			if (ret2)
+				return log_msg_ret("cleanup", ret2);
+		}
+		return log_msg_ret("xfer", ret);
+	}
 
-	return ret2 ? ret2 : ret;
+	return 0;
 }
 
 UCLASS_DRIVER(tpm) = {
diff --git a/include/acpi_s3.h b/include/acpi/acpi_s3.h
similarity index 100%
rename from include/acpi_s3.h
rename to include/acpi/acpi_s3.h
diff --git a/include/acpi/acpi_table.h b/include/acpi/acpi_table.h
new file mode 100644
index 0000000..194be9a
--- /dev/null
+++ b/include/acpi/acpi_table.h
@@ -0,0 +1,512 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Helpers for ACPI table generation
+ *
+ * Based on acpi.c from coreboot
+ *
+ * Copyright 2019 Google LLC
+ *
+ * Copyright (C) 2015, Saket Sinha <saket.sinha89@gmail.com>
+ * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com>
+ */
+
+#ifndef __ACPI_TABLE_H__
+#define __ACPI_TABLE_H__
+
+#define RSDP_SIG		"RSD PTR "	/* RSDP pointer signature */
+#define OEM_ID			"U-BOOT"	/* U-Boot */
+#define OEM_TABLE_ID		"U-BOOTBL"	/* U-Boot Table */
+#define ASLC_ID			"INTL"		/* Intel ASL Compiler */
+
+#define ACPI_RSDP_REV_ACPI_1_0	0
+#define ACPI_RSDP_REV_ACPI_2_0	2
+
+#if !defined(__ACPI__)
+
+/*
+ * RSDP (Root System Description Pointer)
+ * Note: ACPI 1.0 didn't have length, xsdt_address, and ext_checksum
+ */
+struct acpi_rsdp {
+	char signature[8];	/* RSDP signature */
+	u8 checksum;		/* Checksum of the first 20 bytes */
+	char oem_id[6];		/* OEM ID */
+	u8 revision;		/* 0 for ACPI 1.0, others 2 */
+	u32 rsdt_address;	/* Physical address of RSDT (32 bits) */
+	u32 length;		/* Total RSDP length (incl. extended part) */
+	u64 xsdt_address;	/* Physical address of XSDT (64 bits) */
+	u8 ext_checksum;	/* Checksum of the whole table */
+	u8 reserved[3];
+};
+
+/* Generic ACPI header, provided by (almost) all tables */
+struct __packed acpi_table_header {
+	char signature[4];	/* ACPI signature (4 ASCII characters) */
+	u32 length;		/* Table length in bytes (incl. header) */
+	u8 revision;		/* Table version (not ACPI version!) */
+	volatile u8 checksum;	/* To make sum of entire table == 0 */
+	char oem_id[6];		/* OEM identification */
+	char oem_table_id[8];	/* OEM table identification */
+	u32 oem_revision;	/* OEM revision number */
+	char aslc_id[4];	/* ASL compiler vendor ID */
+	u32 aslc_revision;	/* ASL compiler revision number */
+};
+
+/* A maximum number of 32 ACPI tables ought to be enough for now */
+#define MAX_ACPI_TABLES		32
+
+/* RSDT (Root System Description Table) */
+struct acpi_rsdt {
+	struct acpi_table_header header;
+	u32 entry[MAX_ACPI_TABLES];
+};
+
+/* XSDT (Extended System Description Table) */
+struct acpi_xsdt {
+	struct acpi_table_header header;
+	u64 entry[MAX_ACPI_TABLES];
+};
+
+/* FADT Preferred Power Management Profile */
+enum acpi_pm_profile {
+	ACPI_PM_UNSPECIFIED = 0,
+	ACPI_PM_DESKTOP,
+	ACPI_PM_MOBILE,
+	ACPI_PM_WORKSTATION,
+	ACPI_PM_ENTERPRISE_SERVER,
+	ACPI_PM_SOHO_SERVER,
+	ACPI_PM_APPLIANCE_PC,
+	ACPI_PM_PERFORMANCE_SERVER,
+	ACPI_PM_TABLET
+};
+
+/* FADT flags for p_lvl2_lat and p_lvl3_lat */
+#define ACPI_FADT_C2_NOT_SUPPORTED	101
+#define ACPI_FADT_C3_NOT_SUPPORTED	1001
+
+/* FADT Boot Architecture Flags */
+#define ACPI_FADT_LEGACY_FREE		0x00
+#define ACPI_FADT_LEGACY_DEVICES	BIT(0)
+#define ACPI_FADT_8042			BIT(1)
+#define ACPI_FADT_VGA_NOT_PRESENT	BIT(2)
+#define ACPI_FADT_MSI_NOT_SUPPORTED	BIT(3)
+#define ACPI_FADT_NO_PCIE_ASPM_CONTROL	BIT(4)
+
+/* FADT Feature Flags */
+#define ACPI_FADT_WBINVD		BIT(0)
+#define ACPI_FADT_WBINVD_FLUSH		BIT(1)
+#define ACPI_FADT_C1_SUPPORTED		BIT(2)
+#define ACPI_FADT_C2_MP_SUPPORTED	BIT(3)
+#define ACPI_FADT_POWER_BUTTON		BIT(4)
+#define ACPI_FADT_SLEEP_BUTTON		BIT(5)
+#define ACPI_FADT_FIXED_RTC		BIT(6)
+#define ACPI_FADT_S4_RTC_WAKE		BIT(7)
+#define ACPI_FADT_32BIT_TIMER		BIT(8)
+#define ACPI_FADT_DOCKING_SUPPORTED	BIT(9)
+#define ACPI_FADT_RESET_REGISTER	BIT(10)
+#define ACPI_FADT_SEALED_CASE		BIT(11)
+#define ACPI_FADT_HEADLESS		BIT(12)
+#define ACPI_FADT_SLEEP_TYPE		BIT(13)
+#define ACPI_FADT_PCI_EXPRESS_WAKE	BIT(14)
+#define ACPI_FADT_PLATFORM_CLOCK	BIT(15)
+#define ACPI_FADT_S4_RTC_VALID		BIT(16)
+#define ACPI_FADT_REMOTE_POWER_ON	BIT(17)
+#define ACPI_FADT_APIC_CLUSTER		BIT(18)
+#define ACPI_FADT_APIC_PHYSICAL		BIT(19)
+#define ACPI_FADT_HW_REDUCED_ACPI	BIT(20)
+#define ACPI_FADT_LOW_PWR_IDLE_S0	BIT(21)
+
+enum acpi_address_space_type {
+	ACPI_ADDRESS_SPACE_MEMORY = 0,	/* System memory */
+	ACPI_ADDRESS_SPACE_IO,		/* System I/O */
+	ACPI_ADDRESS_SPACE_PCI,		/* PCI config space */
+	ACPI_ADDRESS_SPACE_EC,		/* Embedded controller */
+	ACPI_ADDRESS_SPACE_SMBUS,	/* SMBus */
+	ACPI_ADDRESS_SPACE_PCC = 0x0a,	/* Platform Comm. Channel */
+	ACPI_ADDRESS_SPACE_FIXED = 0x7f	/* Functional fixed hardware */
+};
+
+enum acpi_address_space_size {
+	ACPI_ACCESS_SIZE_UNDEFINED = 0,
+	ACPI_ACCESS_SIZE_BYTE_ACCESS,
+	ACPI_ACCESS_SIZE_WORD_ACCESS,
+	ACPI_ACCESS_SIZE_DWORD_ACCESS,
+	ACPI_ACCESS_SIZE_QWORD_ACCESS
+};
+
+struct acpi_gen_regaddr {
+	u8 space_id;	/* Address space ID */
+	u8 bit_width;	/* Register size in bits */
+	u8 bit_offset;	/* Register bit offset */
+	u8 access_size;	/* Access size */
+	u32 addrl;	/* Register address, low 32 bits */
+	u32 addrh;	/* Register address, high 32 bits */
+};
+
+/* FADT (Fixed ACPI Description Table) */
+struct __packed acpi_fadt {
+	struct acpi_table_header header;
+	u32 firmware_ctrl;
+	u32 dsdt;
+	u8 res1;
+	u8 preferred_pm_profile;
+	u16 sci_int;
+	u32 smi_cmd;
+	u8 acpi_enable;
+	u8 acpi_disable;
+	u8 s4bios_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 p_lvl2_lat;
+	u16 p_lvl3_lat;
+	u16 flush_size;
+	u16 flush_stride;
+	u8 duty_offset;
+	u8 duty_width;
+	u8 day_alrm;
+	u8 mon_alrm;
+	u8 century;
+	u16 iapc_boot_arch;
+	u8 res2;
+	u32 flags;
+	struct acpi_gen_regaddr reset_reg;
+	u8 reset_value;
+	u16 arm_boot_arch;
+	u8 minor_revision;
+	u32 x_firmware_ctl_l;
+	u32 x_firmware_ctl_h;
+	u32 x_dsdt_l;
+	u32 x_dsdt_h;
+	struct acpi_gen_regaddr x_pm1a_evt_blk;
+	struct acpi_gen_regaddr x_pm1b_evt_blk;
+	struct acpi_gen_regaddr x_pm1a_cnt_blk;
+	struct acpi_gen_regaddr x_pm1b_cnt_blk;
+	struct acpi_gen_regaddr x_pm2_cnt_blk;
+	struct acpi_gen_regaddr x_pm_tmr_blk;
+	struct acpi_gen_regaddr x_gpe0_blk;
+	struct acpi_gen_regaddr x_gpe1_blk;
+};
+
+/* FADT TABLE Revision values - note these do not match the ACPI revision */
+#define ACPI_FADT_REV_ACPI_1_0		1
+#define ACPI_FADT_REV_ACPI_2_0		3
+#define ACPI_FADT_REV_ACPI_3_0		4
+#define ACPI_FADT_REV_ACPI_4_0		4
+#define ACPI_FADT_REV_ACPI_5_0		5
+#define ACPI_FADT_REV_ACPI_6_0		6
+
+/* MADT TABLE Revision values - note these do not match the ACPI revision */
+#define ACPI_MADT_REV_ACPI_3_0		2
+#define ACPI_MADT_REV_ACPI_4_0		3
+#define ACPI_MADT_REV_ACPI_5_0		3
+#define ACPI_MADT_REV_ACPI_6_0		5
+
+#define ACPI_MCFG_REV_ACPI_3_0		1
+
+/* IVRS Revision Field */
+#define IVRS_FORMAT_FIXED	0x01	/* Type 10h & 11h only */
+#define IVRS_FORMAT_MIXED	0x02	/* Type 10h, 11h, & 40h */
+
+/* FACS flags */
+#define ACPI_FACS_S4BIOS_F		BIT(0)
+#define ACPI_FACS_64BIT_WAKE_F		BIT(1)
+
+/* FACS (Firmware ACPI Control Structure) */
+struct acpi_facs {
+	char signature[4];		/* "FACS" */
+	u32 length;			/* Length in bytes (>= 64) */
+	u32 hardware_signature;		/* Hardware signature */
+	u32 firmware_waking_vector;	/* Firmware waking vector */
+	u32 global_lock;		/* Global lock */
+	u32 flags;			/* FACS flags */
+	u32 x_firmware_waking_vector_l;	/* X FW waking vector, low */
+	u32 x_firmware_waking_vector_h;	/* X FW waking vector, high */
+	u8 version;			/* Version 2 */
+	u8 res1[3];
+	u32 ospm_flags;			/* OSPM enabled flags */
+	u8 res2[24];
+};
+
+/* MADT flags */
+#define ACPI_MADT_PCAT_COMPAT	BIT(0)
+
+/* MADT (Multiple APIC Description Table) */
+struct acpi_madt {
+	struct acpi_table_header header;
+	u32 lapic_addr;			/* Local APIC address */
+	u32 flags;			/* Multiple APIC flags */
+};
+
+/* MADT: APIC Structure Type*/
+enum acpi_apic_types {
+	ACPI_APIC_LAPIC	= 0,		/* Processor local APIC */
+	ACPI_APIC_IOAPIC,		/* I/O APIC */
+	ACPI_APIC_IRQ_SRC_OVERRIDE,	/* Interrupt source override */
+	ACPI_APIC_NMI_SRC,		/* NMI source */
+	ACPI_APIC_LAPIC_NMI,		/* Local APIC NMI */
+	ACPI_APIC_LAPIC_ADDR_OVERRIDE,	/* Local APIC address override */
+	ACPI_APIC_IOSAPIC,		/* I/O SAPIC */
+	ACPI_APIC_LSAPIC,		/* Local SAPIC */
+	ACPI_APIC_PLATFORM_IRQ_SRC,	/* Platform interrupt sources */
+	ACPI_APIC_LX2APIC,		/* Processor local x2APIC */
+	ACPI_APIC_LX2APIC_NMI,		/* Local x2APIC NMI */
+};
+
+/* MADT: Processor Local APIC Structure */
+
+#define LOCAL_APIC_FLAG_ENABLED		BIT(0)
+
+struct acpi_madt_lapic {
+	u8 type;		/* Type (0) */
+	u8 length;		/* Length in bytes (8) */
+	u8 processor_id;	/* ACPI processor ID */
+	u8 apic_id;		/* Local APIC ID */
+	u32 flags;		/* Local APIC flags */
+};
+
+/* MADT: I/O APIC Structure */
+struct acpi_madt_ioapic {
+	u8 type;		/* Type (1) */
+	u8 length;		/* Length in bytes (12) */
+	u8 ioapic_id;		/* I/O APIC ID */
+	u8 reserved;
+	u32 ioapic_addr;	/* I/O APIC address */
+	u32 gsi_base;		/* Global system interrupt base */
+};
+
+/* MADT: Interrupt Source Override Structure */
+struct __packed acpi_madt_irqoverride {
+	u8 type;		/* Type (2) */
+	u8 length;		/* Length in bytes (10) */
+	u8 bus;			/* ISA (0) */
+	u8 source;		/* Bus-relative int. source (IRQ) */
+	u32 gsirq;		/* Global system interrupt */
+	u16 flags;		/* MPS INTI flags */
+};
+
+/* MADT: Local APIC NMI Structure */
+struct __packed acpi_madt_lapic_nmi {
+	u8 type;		/* Type (4) */
+	u8 length;		/* Length in bytes (6) */
+	u8 processor_id;	/* ACPI processor ID */
+	u16 flags;		/* MPS INTI flags */
+	u8 lint;		/* Local APIC LINT# */
+};
+
+/* MCFG (PCI Express MMIO config space BAR description table) */
+struct acpi_mcfg {
+	struct acpi_table_header header;
+	u8 reserved[8];
+};
+
+struct acpi_mcfg_mmconfig {
+	u32 base_address_l;
+	u32 base_address_h;
+	u16 pci_segment_group_number;
+	u8 start_bus_number;
+	u8 end_bus_number;
+	u8 reserved[4];
+};
+
+/* PM1_CNT bit defines */
+#define PM1_CNT_SCI_EN		BIT(0)
+
+/* ACPI global NVS structure */
+struct acpi_global_nvs;
+
+/* CSRT (Core System Resource Table) */
+struct acpi_csrt {
+	struct acpi_table_header header;
+};
+
+struct acpi_csrt_group {
+	u32 length;
+	u32 vendor_id;
+	u32 subvendor_id;
+	u16 device_id;
+	u16 subdevice_id;
+	u16 revision;
+	u16 reserved;
+	u32 shared_info_length;
+};
+
+struct acpi_csrt_shared_info {
+	u16 major_version;
+	u16 minor_version;
+	u32 mmio_base_low;
+	u32 mmio_base_high;
+	u32 gsi_interrupt;
+	u8 interrupt_polarity;
+	u8 interrupt_mode;
+	u8 num_channels;
+	u8 dma_address_width;
+	u16 base_request_line;
+	u16 num_handshake_signals;
+	u32 max_block_size;
+};
+
+enum dmar_type {
+	DMAR_DRHD = 0,
+	DMAR_RMRR = 1,
+	DMAR_ATSR = 2,
+	DMAR_RHSA = 3,
+	DMAR_ANDD = 4
+};
+
+enum {
+	DRHD_INCLUDE_PCI_ALL = BIT(0)
+};
+
+enum dmar_flags {
+	DMAR_INTR_REMAP			= BIT(0),
+	DMAR_X2APIC_OPT_OUT		= BIT(1),
+	DMAR_CTRL_PLATFORM_OPT_IN_FLAG	= BIT(2),
+};
+
+struct dmar_entry {
+	u16 type;
+	u16 length;
+	u8 flags;
+	u8 reserved;
+	u16 segment;
+	u64 bar;
+};
+
+struct dmar_rmrr_entry {
+	u16 type;
+	u16 length;
+	u16 reserved;
+	u16 segment;
+	u64 bar;
+	u64 limit;
+};
+
+/* DMAR (DMA Remapping Reporting Structure) */
+struct __packed acpi_dmar {
+	struct acpi_table_header header;
+	u8 host_address_width;
+	u8 flags;
+	u8 reserved[10];
+	struct dmar_entry structure[0];
+};
+
+/* DBG2 definitions are partially used for SPCR interface_type */
+
+/* Types for port_type field */
+
+#define ACPI_DBG2_SERIAL_PORT		0x8000
+#define ACPI_DBG2_1394_PORT		0x8001
+#define ACPI_DBG2_USB_PORT		0x8002
+#define ACPI_DBG2_NET_PORT		0x8003
+
+/* Subtypes for port_subtype field */
+
+#define ACPI_DBG2_16550_COMPATIBLE	0x0000
+#define ACPI_DBG2_16550_SUBSET		0x0001
+#define ACPI_DBG2_ARM_PL011		0x0003
+#define ACPI_DBG2_ARM_SBSA_32BIT	0x000D
+#define ACPI_DBG2_ARM_SBSA_GENERIC	0x000E
+#define ACPI_DBG2_ARM_DCC		0x000F
+#define ACPI_DBG2_BCM2835		0x0010
+
+#define ACPI_DBG2_1394_STANDARD		0x0000
+
+#define ACPI_DBG2_USB_XHCI		0x0000
+#define ACPI_DBG2_USB_EHCI		0x0001
+
+#define ACPI_DBG2_UNKNOWN		0x00FF
+
+/* SPCR (Serial Port Console Redirection table) */
+struct __packed acpi_spcr {
+	struct acpi_table_header header;
+	u8 interface_type;
+	u8 reserved[3];
+	struct acpi_gen_regaddr serial_port;
+	u8 interrupt_type;
+	u8 pc_interrupt;
+	u32 interrupt;		/* Global system interrupt */
+	u8 baud_rate;
+	u8 parity;
+	u8 stop_bits;
+	u8 flow_control;
+	u8 terminal_type;
+	u8 reserved1;
+	u16 pci_device_id;	/* Must be 0xffff if not PCI device */
+	u16 pci_vendor_id;	/* Must be 0xffff if not PCI device */
+	u8 pci_bus;
+	u8 pci_device;
+	u8 pci_function;
+	u32 pci_flags;
+	u8 pci_segment;
+	u32 reserved2;
+};
+
+/* Tables defined/reserved by ACPI and generated by U-Boot */
+enum acpi_tables {
+	ACPITAB_BERT,
+	ACPITAB_DBG2,
+	ACPITAB_DMAR,
+	ACPITAB_DSDT,
+	ACPITAB_ECDT,
+	ACPITAB_FACS,
+	ACPITAB_FADT,
+	ACPITAB_HEST,
+	ACPITAB_HPET,
+	ACPITAB_IVRS,
+	ACPITAB_MADT,
+	ACPITAB_MCFG,
+	ACPITAB_NHLT,
+	ACPITAB_RSDP,
+	ACPITAB_RSDT,
+	ACPITAB_SLIT,
+	ACPITAB_SPCR,
+	ACPITAB_SPMI,
+	ACPITAB_SRAT,
+	ACPITAB_SSDT,
+	ACPITAB_TCPA,
+	ACPITAB_TPM2,
+	ACPITAB_VFCT,
+	ACPITAB_XSDT,
+
+	ACPITAB_COUNT,
+};
+
+/**
+ * acpi_get_table_revision() - Get the revision number generated for a table
+ *
+ * This keeps the version-number information in one place
+ *
+ * @table: ACPI table to check
+ * @return version number that U-Boot generates
+ */
+int acpi_get_table_revision(enum acpi_tables table);
+
+/**
+ * acpi_create_dmar() - Create a DMA Remapping Reporting (DMAR) table
+ *
+ * @dmar: Place to put the table
+ * @flags: DMAR flags to use
+ * @return 0 if OK, -ve on error
+ */
+int acpi_create_dmar(struct acpi_dmar *dmar, enum dmar_flags flags);
+
+#endif /* !__ACPI__*/
+
+#include <asm/acpi_table.h>
+
+#endif /* __ACPI_TABLE_H__ */
diff --git a/include/configs/stm32mp1.h b/include/configs/stm32mp1.h
index 42717c1..2ba4fb1 100644
--- a/include/configs/stm32mp1.h
+++ b/include/configs/stm32mp1.h
@@ -10,7 +10,7 @@
 #include <linux/sizes.h>
 #include <asm/arch/stm32.h>
 
-#ifndef CONFIG_STM32MP1_TRUSTED
+#ifndef CONFIG_TFABOOT
 /* PSCI support */
 #define CONFIG_ARMV7_PSCI_1_0
 #define CONFIG_ARMV7_SECURE_BASE		STM32_SYSRAM_BASE
diff --git a/include/cpu.h b/include/cpu.h
index 28dd48f..6b1b6b3 100644
--- a/include/cpu.h
+++ b/include/cpu.h
@@ -44,10 +44,12 @@
  *
  * @cpu_freq:	Current CPU frequency in Hz
  * @features:	Flags for supported CPU features
+ * @address_width:	Width of the CPU address space in bits (e.g. 32)
  */
 struct cpu_info {
 	ulong cpu_freq;
 	ulong features;
+	uint address_width;
 };
 
 struct cpu_ops {
diff --git a/include/dm/acpi.h b/include/dm/acpi.h
new file mode 100644
index 0000000..4925791
--- /dev/null
+++ b/include/dm/acpi.h
@@ -0,0 +1,77 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Core ACPI (Advanced Configuration and Power Interface) support
+ *
+ * Copyright 2019 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#ifndef __DM_ACPI_H__
+#define __DM_ACPI_H__
+
+/* Allow operations to be optional for ACPI */
+#if CONFIG_IS_ENABLED(ACPIGEN)
+#define ACPI_OPS_PTR(_ptr)	.acpi_ops	= _ptr,
+#else
+#define ACPI_OPS_PTR(_ptr)
+#endif
+
+/* Length of an ACPI name string, excluding nul terminator */
+#define ACPI_NAME_LEN	4
+
+/* Length of an ACPI name string including nul terminator */
+#define ACPI_NAME_MAX	(ACPI_NAME_LEN + 1)
+
+#if !defined(__ACPI__)
+
+/**
+ * struct acpi_ops - ACPI operations supported by driver model
+ */
+struct acpi_ops {
+	/**
+	 * get_name() - Obtain the ACPI name of a device
+	 *
+	 * @dev: Device to check
+	 * @out_name: Place to put the name, must hold at least ACPI_NAME_MAX
+	 *	bytes
+	 * @return 0 if OK, -ENOENT if no name is available, other -ve value on
+	 *	other error
+	 */
+	int (*get_name)(const struct udevice *dev, char *out_name);
+};
+
+#define device_get_acpi_ops(dev)	((dev)->driver->acpi_ops)
+
+/**
+ * acpi_get_name() - Obtain the ACPI name of a device
+ *
+ * @dev: Device to check
+ * @out_name: Place to put the name, must hold at least ACPI_NAME_MAX
+ *	bytes
+ * @return 0 if OK, -ENOENT if no name is available, other -ve value on
+ *	other error
+ */
+int acpi_get_name(const struct udevice *dev, char *out_name);
+
+/**
+ * acpi_copy_name() - Copy an ACPI name to an output buffer
+ *
+ * This convenience function can be used to return a literal string as a name
+ * in functions that implement the get_name() method.
+ *
+ * For example:
+ *
+ *	static int mydev_get_name(const struct udevice *dev, char *out_name)
+ *	{
+ *		return acpi_copy_name(out_name, "WIBB");
+ *	}
+ *
+ * @out_name: Place to put the name
+ * @name: Name to copy
+ * @return 0 (always)
+ */
+int acpi_copy_name(char *out_name, const char *name);
+
+#endif /* __ACPI__ */
+
+#endif
diff --git a/include/dm/device.h b/include/dm/device.h
index a56164b..975eec5 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -80,18 +80,21 @@
  */
 enum {
 	/* Normal remove, remove all devices */
-	DM_REMOVE_NORMAL     = 1 << 0,
+	DM_REMOVE_NORMAL	= 1 << 0,
 
 	/* Remove devices with active DMA */
-	DM_REMOVE_ACTIVE_DMA = DM_FLAG_ACTIVE_DMA,
+	DM_REMOVE_ACTIVE_DMA	= DM_FLAG_ACTIVE_DMA,
 
 	/* Remove devices which need some final OS preparation steps */
-	DM_REMOVE_OS_PREPARE = DM_FLAG_OS_PREPARE,
+	DM_REMOVE_OS_PREPARE	= DM_FLAG_OS_PREPARE,
 
 	/* Add more use cases here */
 
 	/* Remove devices with any active flag */
-	DM_REMOVE_ACTIVE_ALL = DM_REMOVE_ACTIVE_DMA | DM_REMOVE_OS_PREPARE,
+	DM_REMOVE_ACTIVE_ALL	= DM_REMOVE_ACTIVE_DMA | DM_REMOVE_OS_PREPARE,
+
+	/* Don't power down any attached power domains */
+	DM_REMOVE_NO_PD		= 1 << 1,
 };
 
 /**
@@ -245,6 +248,8 @@
  * pointers defined by the driver, to implement driver functions required by
  * the uclass.
  * @flags: driver flags - see DM_FLAGS_...
+ * @acpi_ops: Advanced Configuration and Power Interface (ACPI) operations,
+ * allowing the device to add things to the ACPI tables passed to Linux
  */
 struct driver {
 	char *name;
@@ -264,6 +269,9 @@
 	int per_child_platdata_auto_alloc_size;
 	const void *ops;	/* driver-specific operations */
 	uint32_t flags;
+#if CONFIG_IS_ENABLED(ACPIGEN)
+	struct acpi_ops *acpi_ops;
+#endif
 };
 
 /* Declare a new U-Boot driver */
diff --git a/include/dm/of_access.h b/include/dm/of_access.h
index 13fedb7..92876b3 100644
--- a/include/dm/of_access.h
+++ b/include/dm/of_access.h
@@ -235,6 +235,25 @@
 int of_read_u32(const struct device_node *np, const char *propname, u32 *outp);
 
 /**
+ * of_read_u32_index() - Find and read a 32-bit value from a multi-value
+ *                       property
+ *
+ * Search for a property in a device node and read a 32-bit value from
+ * it.
+ *
+ * @np:		device node from which the property value is to be read.
+ * @propname:	name of the property to be searched.
+ * @index:	index of the u32 in the list of values
+ * @outp:	pointer to return value, modified only if return value is 0.
+ *
+ * @return 0 on success, -EINVAL if the property does not exist,
+ * -ENODATA if property does not have a value, and -EOVERFLOW if the
+ * property data isn't large enough.
+ */
+int of_read_u32_index(const struct device_node *np, const char *propname,
+		      int index, u32 *outp);
+
+/**
  * of_read_u64() - Find and read a 64-bit integer from a property
  *
  * Search for a property in a device node and read a 64-bit value from
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h
index b5a50e8..ce5e366 100644
--- a/include/dm/ofnode.h
+++ b/include/dm/ofnode.h
@@ -203,6 +203,18 @@
 int ofnode_read_u32(ofnode node, const char *propname, u32 *outp);
 
 /**
+ * ofnode_read_u32_index() - Read a 32-bit integer from a multi-value property
+ *
+ * @ref:	valid node reference to read property from
+ * @propname:	name of the property to read from
+ * @index:	index of the integer to return
+ * @outp:	place to put value (if found)
+ * @return 0 if OK, -ve on error
+ */
+int ofnode_read_u32_index(ofnode node, const char *propname, int index,
+			  u32 *outp);
+
+/**
  * ofnode_read_s32() - Read a 32-bit integer from a property
  *
  * @ref:	valid node reference to read property from
@@ -227,6 +239,19 @@
 u32 ofnode_read_u32_default(ofnode ref, const char *propname, u32 def);
 
 /**
+ * ofnode_read_u32_index_default() - Read a 32-bit integer from a multi-value
+ *                                   property
+ *
+ * @ref:	valid node reference to read property from
+ * @propname:	name of the property to read from
+ * @index:	index of the integer to return
+ * @def:	default value to return if the property has no value
+ * @return property value, or @def if not found
+ */
+u32 ofnode_read_u32_index_default(ofnode ref, const char *propname, int index,
+				  u32 def);
+
+/**
  * ofnode_read_s32_default() - Read a 32-bit integer from a property
  *
  * @ref:	valid node reference to read property from
diff --git a/include/dm/read.h b/include/dm/read.h
index da8c7f2..77d3bc8 100644
--- a/include/dm/read.h
+++ b/include/dm/read.h
@@ -67,6 +67,32 @@
 			 int def);
 
 /**
+ * dev_read_u32_index() - read an indexed 32-bit integer from a device's DT
+ *                        property
+ *
+ * @dev:	device to read DT property from
+ * @propname:	name of the property to read from
+ * @index:	index of the integer to return
+ * @outp:	place to put value (if found)
+ * @return 0 if OK, -ve on error
+ */
+int dev_read_u32_index(struct udevice *dev, const char *propname, int index,
+		       u32 *outp);
+
+/**
+ * dev_read_u32_index_default() - read an indexed 32-bit integer from a device's
+ *                                DT property
+ *
+ * @dev:	device to read DT property from
+ * @propname:	name of the property to read from
+ * @index:	index of the integer to return
+ * @def:	default value to return if the property has no value
+ * @return property value, or @def if not found
+ */
+u32 dev_read_u32_index_default(struct udevice *dev, const char *propname,
+			       int index, u32 def);
+
+/**
  * dev_read_s32() - read a signed 32-bit integer from a device's DT property
  *
  * @dev:	device to read DT property from
@@ -621,6 +647,20 @@
 	return ofnode_read_u32_default(dev_ofnode(dev), propname, def);
 }
 
+static inline int dev_read_u32_index(struct udevice *dev,
+				     const char *propname, int index, u32 *outp)
+{
+	return ofnode_read_u32_index(dev_ofnode(dev), propname, index, outp);
+}
+
+static inline u32 dev_read_u32_index_default(struct udevice *dev,
+					     const char *propname, int index,
+					     u32 def)
+{
+	return ofnode_read_u32_index_default(dev_ofnode(dev), propname, index,
+					     def);
+}
+
 static inline int dev_read_s32(const struct udevice *dev,
 			       const char *propname, s32 *outp)
 {
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 598f65e..37ada51 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -20,6 +20,7 @@
 	UCLASS_TEST_PROBE,
 	UCLASS_TEST_DUMMY,
 	UCLASS_TEST_DEVRES,
+	UCLASS_TEST_ACPI,
 	UCLASS_SPI_EMUL,	/* sandbox SPI device emulator */
 	UCLASS_I2C_EMUL,	/* sandbox I2C device emulator */
 	UCLASS_I2C_EMUL_PARENT,	/* parent for I2C device emulators */
diff --git a/include/dm/util.h b/include/dm/util.h
index 0ccb3fb..23f8deb 100644
--- a/include/dm/util.h
+++ b/include/dm/util.h
@@ -42,31 +42,4 @@
 /* Dump out a list of drivers */
 void dm_dump_drivers(void);
 
-/**
- * Check if an of node should be or was bound before relocation.
- *
- * Devicetree nodes can be marked as needed to be bound
- * in the loader stages via special devicetree properties.
- *
- * Before relocation this function can be used to check if nodes
- * are required in either SPL or TPL stages.
- *
- * After relocation and jumping into the real U-Boot binary
- * it is possible to determine if a node was bound in one of
- * SPL/TPL stages.
- *
- * There are 4 settings currently in use
- * - u-boot,dm-pre-proper: U-Boot proper pre-relocation only
- * - u-boot,dm-pre-reloc: legacy and indicates any of TPL or SPL
- *   Existing platforms only use it to indicate nodes needed in
- *   SPL. Should probably be replaced by u-boot,dm-spl for
- *   existing platforms.
- * - u-boot,dm-spl: SPL and U-Boot pre-relocation
- * - u-boot,dm-tpl: TPL and U-Boot pre-relocation
- * @node: of node
- *
- * Returns true if node is needed in SPL/TL, false otherwise.
- */
-bool dm_ofnode_pre_reloc(ofnode node);
-
 #endif
diff --git a/include/log.h b/include/log.h
index 62fb8af..cf32351 100644
--- a/include/log.h
+++ b/include/log.h
@@ -51,6 +51,8 @@
 	LOGC_SANDBOX,	/* Related to the sandbox board */
 	LOGC_BLOBLIST,	/* Bloblist */
 	LOGC_DEVRES,	/* Device resources (devres_... functions) */
+	/* Advanced Configuration and Power Interface (ACPI) */
+	LOGC_ACPI,
 
 	LOGC_COUNT,	/* Number of log categories */
 	LOGC_END,	/* Sentinel value for a list of log categories */
@@ -115,11 +117,11 @@
 #define log_io(_fmt...)		log(LOG_CATEGORY, LOGL_DEBUG_IO, ##_fmt)
 #else
 #define _LOG_MAX_LEVEL LOGL_INFO
-#define log_err(_fmt...)	log_nop(LOG_CATEGORY, LOGL_ERR, ##_fmt)
-#define log_warning(_fmt...)	log_nop(LOG_CATEGORY, LOGL_WARNING, ##_fmt)
-#define log_notice(_fmt...)	log_nop(LOG_CATEGORY, LOGL_NOTICE, ##_fmt)
-#define log_info(_fmt...)	log_nop(LOG_CATEGORY, LOGL_INFO, ##_fmt)
-#define log_debug(_fmt...)	log_nop(LOG_CATEGORY, LOGL_DEBUG, ##_fmt)
+#define log_err(_fmt, ...)	printf(_fmt, ##__VA_ARGS__)
+#define log_warning(_fmt, ...)	printf(_fmt, ##__VA_ARGS__)
+#define log_notice(_fmt, ...)	printf(_fmt, ##__VA_ARGS__)
+#define log_info(_fmt, ...)	printf(_fmt, ##__VA_ARGS__)
+#define log_debug(_fmt, ...)	debug(_fmt, ##__VA_ARGS__)
 #define log_content(_fmt...)	log_nop(LOG_CATEGORY, \
 					LOGL_DEBUG_CONTENT, ##_fmt)
 #define log_io(_fmt...)		log_nop(LOG_CATEGORY, LOGL_DEBUG_IO, ##_fmt)
diff --git a/include/serial.h b/include/serial.h
index 104f34f..54b21a0 100644
--- a/include/serial.h
+++ b/include/serial.h
@@ -139,6 +139,7 @@
  * @reg_width:	size (in bytes) of the IO accesses to the registers
  * @reg_offset:	offset to apply to the @addr from the start of the registers
  * @reg_shift:	quantity to shift the register offsets by
+ * @clock:	UART base clock speed in Hz
  * @baudrate:	baud rate
  */
 struct serial_device_info {
@@ -148,10 +149,12 @@
 	u8 reg_width;
 	u8 reg_offset;
 	u8 reg_shift;
+	unsigned int clock;
 	unsigned int baudrate;
 };
 
 #define SERIAL_DEFAULT_ADDRESS	0xBADACCE5
+#define SERIAL_DEFAULT_CLOCK	(16 * 115200)
 
 /**
  * struct struct dm_serial_ops - Driver model serial operations
diff --git a/include/spi.h b/include/spi.h
index 852f570..2b4929f 100644
--- a/include/spi.h
+++ b/include/spi.h
@@ -67,6 +67,39 @@
 #endif /* CONFIG_DM_SPI */
 
 /**
+ * enum spi_clock_phase - indicates  the clock phase to use for SPI (CPHA)
+ *
+ * @SPI_CLOCK_PHASE_FIRST: Data sampled on the first phase
+ * @SPI_CLOCK_PHASE_SECOND: Data sampled on the second phase
+ */
+enum spi_clock_phase {
+	SPI_CLOCK_PHASE_FIRST,
+	SPI_CLOCK_PHASE_SECOND,
+};
+
+/**
+ * enum spi_wire_mode - indicates the number of wires used for SPI
+ *
+ * @SPI_4_WIRE_MODE: Normal bidirectional mode with MOSI and MISO
+ * @SPI_3_WIRE_MODE: Unidirectional version with a single data line SISO
+ */
+enum spi_wire_mode {
+	SPI_4_WIRE_MODE,
+	SPI_3_WIRE_MODE,
+};
+
+/**
+ * enum spi_polarity - indicates the polarity of the SPI bus (CPOL)
+ *
+ * @SPI_POLARITY_LOW: Clock is low in idle state
+ * @SPI_POLARITY_HIGH: Clock is high in idle state
+ */
+enum spi_polarity {
+	SPI_POLARITY_LOW,
+	SPI_POLARITY_HIGH,
+};
+
+/**
  * struct spi_slave - Representation of a SPI slave
  *
  * For driver model this is the per-child data used by the SPI bus. It can
diff --git a/include/test/log.h b/include/test/log.h
new file mode 100644
index 0000000..c661cde
--- /dev/null
+++ b/include/test/log.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2020, Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * Tests for logging functions
+ */
+
+#ifndef __TEST_LOG_H__
+#define __TEST_LOG_H__
+
+#include <test/test.h>
+
+/* Declare a new logging test */
+#define LOG_TEST(_name) UNIT_TEST(_name, 0, log_test)
+
+#endif /* __TEST_LOG_H__ */
diff --git a/include/test/suites.h b/include/test/suites.h
index 0748185..39ad81a 100644
--- a/include/test/suites.h
+++ b/include/test/suites.h
@@ -30,6 +30,7 @@
 int do_ut_dm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
 int do_ut_env(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
 int do_ut_lib(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+int do_ut_log(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
 int do_ut_optee(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
 int do_ut_overlay(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
 int do_ut_time(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
diff --git a/include/test/ut.h b/include/test/ut.h
index 04df8ba..b05d719 100644
--- a/include/test/ut.h
+++ b/include/test/ut.h
@@ -8,6 +8,7 @@
 #ifndef __TEST_UT_H
 #define __TEST_UT_H
 
+#include <hexdump.h>
 #include <linux/err.h>
 
 struct unit_test_state;
@@ -104,6 +105,22 @@
 	}								\
 }
 
+/* Assert that two 64 int expressions are equal */
+#define ut_asserteq_64(expr1, expr2) {					\
+	u64 _val1 = (expr1), _val2 = (expr2);				\
+									\
+	if (_val1 != _val2) {						\
+		ut_failf(uts, __FILE__, __LINE__, __func__,		\
+			 #expr1 " == " #expr2,				\
+			 "Expected %#llx (%lld), got %#llx (%lld)",	\
+			 (unsigned long long)_val1,			\
+			 (unsigned long long)_val1,			\
+			 (unsigned long long)_val2,			\
+			 (unsigned long long)_val2);			\
+		return CMD_RET_FAILURE;					\
+	}								\
+}
+
 /* Assert that two string expressions are equal */
 #define ut_asserteq_str(expr1, expr2) {					\
 	const char *_val1 = (expr1), *_val2 = (expr2);			\
diff --git a/lib/Makefile b/lib/Makefile
index 32bf3f3..5f88d92 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -58,6 +58,7 @@
 obj-$(CONFIG_TPM_V2) += tpm-v2.o
 endif
 
+obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi/
 obj-$(CONFIG_$(SPL_)RSA) += rsa/
 obj-$(CONFIG_SHA1) += sha1.o
 obj-$(CONFIG_SHA256) += sha256.o
diff --git a/lib/acpi/Makefile b/lib/acpi/Makefile
new file mode 100644
index 0000000..660491e
--- /dev/null
+++ b/lib/acpi/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += acpi_table.o
diff --git a/lib/acpi/acpi_table.c b/lib/acpi/acpi_table.c
new file mode 100644
index 0000000..4633dcb
--- /dev/null
+++ b/lib/acpi/acpi_table.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Generic code used to generate ACPI tables
+ *
+ * Copyright 2019 Google LLC
+ */
+
+#include <common.h>
+#include <acpi/acpi_table.h>
+#include <dm.h>
+#include <cpu.h>
+
+/* Temporary change to ensure bisectability */
+#ifndef CONFIG_SANDBOX
+int acpi_create_dmar(struct acpi_dmar *dmar, enum dmar_flags flags)
+{
+	struct acpi_table_header *header = &dmar->header;
+	struct cpu_info info;
+	struct udevice *cpu;
+	int ret;
+
+	ret = uclass_first_device(UCLASS_CPU, &cpu);
+	if (ret)
+		return log_msg_ret("cpu", ret);
+	ret = cpu_get_info(cpu, &info);
+	if (ret)
+		return log_msg_ret("info", ret);
+	memset((void *)dmar, 0, sizeof(struct acpi_dmar));
+
+	/* Fill out header fields. */
+	acpi_fill_header(&dmar->header, "DMAR");
+	header->length = sizeof(struct acpi_dmar);
+	header->revision = acpi_get_table_revision(ACPITAB_DMAR);
+
+	dmar->host_address_width = info.address_width - 1;
+	dmar->flags = flags;
+
+	return 0;
+}
+#endif
+
+int acpi_get_table_revision(enum acpi_tables table)
+{
+	switch (table) {
+	case ACPITAB_FADT:
+		return ACPI_FADT_REV_ACPI_3_0;
+	case ACPITAB_MADT:
+		return ACPI_MADT_REV_ACPI_3_0;
+	case ACPITAB_MCFG:
+		return ACPI_MCFG_REV_ACPI_3_0;
+	case ACPITAB_TCPA:
+		/* This version and the rest are open-coded */
+		return 2;
+	case ACPITAB_TPM2:
+		return 4;
+	case ACPITAB_SSDT: /* ACPI 3.0 upto 6.3: 2 */
+		return 2;
+	case ACPITAB_SRAT: /* ACPI 2.0: 1, ACPI 3.0: 2, ACPI 4.0 to 6.3: 3 */
+		return 1; /* TODO Should probably be upgraded to 2 */
+	case ACPITAB_DMAR:
+		return 1;
+	case ACPITAB_SLIT: /* ACPI 2.0 upto 6.3: 1 */
+		return 1;
+	case ACPITAB_SPMI: /* IMPI 2.0 */
+		return 5;
+	case ACPITAB_HPET: /* Currently 1. Table added in ACPI 2.0 */
+		return 1;
+	case ACPITAB_VFCT: /* ACPI 2.0/3.0/4.0: 1 */
+		return 1;
+	case ACPITAB_IVRS:
+		return IVRS_FORMAT_FIXED;
+	case ACPITAB_DBG2:
+		return 0;
+	case ACPITAB_FACS: /* ACPI 2.0/3.0: 1, ACPI 4.0 to 6.3: 2 */
+		return 1;
+	case ACPITAB_RSDT: /* ACPI 1.0 upto 6.3: 1 */
+		return 1;
+	case ACPITAB_XSDT: /* ACPI 2.0 upto 6.3: 1 */
+		return 1;
+	case ACPITAB_RSDP: /* ACPI 2.0 upto 6.3: 2 */
+		return 2;
+	case ACPITAB_HEST:
+		return 1;
+	case ACPITAB_NHLT:
+		return 5;
+	case ACPITAB_BERT:
+		return 1;
+	case ACPITAB_SPCR:
+		return 2;
+	default:
+		return -EINVAL;
+	}
+}
diff --git a/lib/efi_loader/efi_acpi.c b/lib/efi_loader/efi_acpi.c
index a4e5e53..9ae9c25 100644
--- a/lib/efi_loader/efi_acpi.c
+++ b/lib/efi_loader/efi_acpi.c
@@ -7,7 +7,7 @@
 
 #include <common.h>
 #include <efi_loader.h>
-#include <asm/acpi_table.h>
+#include <acpi/acpi_table.h>
 
 static const efi_guid_t acpi_guid = EFI_ACPI_TABLE_GUID;
 
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index eb11fc8..9ecfa2a 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -1433,14 +1433,9 @@
 			const struct fdt_memory *carveout)
 {
 	uint32_t phandle;
-	int err, offset;
+	int err, offset, len;
 	fdt32_t value;
-
-	/* XXX implement support for multiple phandles */
-	if (index > 0) {
-		debug("invalid index %u\n", index);
-		return -FDT_ERR_BADOFFSET;
-	}
+	void *prop;
 
 	err = fdtdec_add_reserved_memory(blob, name, carveout, &phandle);
 	if (err < 0) {
@@ -1456,10 +1451,31 @@
 
 	value = cpu_to_fdt32(phandle);
 
+	if (!fdt_getprop(blob, offset, prop_name, &len)) {
+		if (len == -FDT_ERR_NOTFOUND)
+			len = 0;
+		else
+			return len;
+	}
+
+	if ((index + 1) * sizeof(value) > len) {
+		err = fdt_setprop_placeholder(blob, offset, prop_name,
+					      (index + 1) * sizeof(value),
+					      &prop);
+		if (err < 0) {
+			debug("failed to resize reserved memory property: %s\n",
+			      fdt_strerror(err));
+			return err;
+		}
+	}
+
-	err = fdt_setprop(blob, offset, prop_name, &value, sizeof(value));
+	err = fdt_setprop_inplace_namelen_partial(blob, offset, prop_name,
+						  strlen(prop_name),
+						  index * sizeof(value),
+						  &value, sizeof(value));
 	if (err < 0) {
-		debug("failed to set %s property for node %s: %d\n", prop_name,
-		      node, err);
+		debug("failed to update %s property for node %s: %s\n",
+		      prop_name, node, fdt_strerror(err));
 		return err;
 	}
 
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 8decb0e..1c8cb74 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -437,8 +437,8 @@
 
 quiet_cmd_acpi_c_asl= ASL     $<
 cmd_acpi_c_asl=         \
-	$(CPP) -x assembler-with-cpp -D__ASSEMBLY__ -P $(UBOOTINCLUDE) \
-		-o $(ASL_TMP) $< && \
+	$(CPP) -x assembler-with-cpp -D__ASSEMBLY__ -D__ACPI__ \
+		-P $(UBOOTINCLUDE) -o $(ASL_TMP) $< && \
 	iasl -p $@ -tc $(ASL_TMP) $(if $(KBUILD_VERBOSE:1=), >/dev/null) && \
 	mv $(patsubst %.c,%.hex,$@) $@
 
diff --git a/test/Kconfig b/test/Kconfig
index 0157e0b..28704a2 100644
--- a/test/Kconfig
+++ b/test/Kconfig
@@ -40,6 +40,15 @@
 
 endif
 
+config UT_LOG
+	bool "Unit tests for logging functions"
+	depends on UNIT_TEST
+	default y
+	help
+	  Enables the 'ut log' command which tests logging functions like
+	  log_err().
+	  See also CONFIG_LOG_TEST which provides the 'log test' command.
+
 config UT_TIME
 	bool "Unit tests for time functions"
 	depends on UNIT_TEST
diff --git a/test/Makefile b/test/Makefile
index 2fe41f4..2971d0d 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -10,5 +10,5 @@
 obj-$(CONFIG_SANDBOX) += print_ut.o
 obj-$(CONFIG_UT_TIME) += time_ut.o
 obj-$(CONFIG_UT_UNICODE) += unicode_ut.o
-obj-$(CONFIG_$(SPL_)LOG) += log/
+obj-y += log/
 obj-$(CONFIG_UNIT_TEST) += lib/
diff --git a/test/cmd_ut.c b/test/cmd_ut.c
index a3a9d49..7fdcdbb 100644
--- a/test/cmd_ut.c
+++ b/test/cmd_ut.c
@@ -60,6 +60,9 @@
 #ifdef CONFIG_UT_LIB
 	U_BOOT_CMD_MKENT(lib, CONFIG_SYS_MAXARGS, 1, do_ut_lib, "", ""),
 #endif
+#ifdef CONFIG_UT_LOG
+	U_BOOT_CMD_MKENT(log, CONFIG_SYS_MAXARGS, 1, do_ut_log, "", ""),
+#endif
 #ifdef CONFIG_UT_TIME
 	U_BOOT_CMD_MKENT(time, CONFIG_SYS_MAXARGS, 1, do_ut_time, "", ""),
 #endif
@@ -125,6 +128,9 @@
 #ifdef CONFIG_UT_LIB
 	"ut lib [test-name] - test library functions\n"
 #endif
+#ifdef CONFIG_UT_LOG
+	"ut log [test-name] - test logging functions\n"
+#endif
 #ifdef CONFIG_UT_OPTEE
 	"ut optee [test-name]\n"
 #endif
diff --git a/test/dm/Makefile b/test/dm/Makefile
index dd1ceff..f55874c 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -13,6 +13,7 @@
 # subsystem you must add sandbox tests here.
 obj-$(CONFIG_UT_DM) += core.o
 ifneq ($(CONFIG_SANDBOX),)
+obj-$(CONFIG_ACPIGEN) += acpi.o
 obj-$(CONFIG_SOUND) += audio.o
 obj-$(CONFIG_BLK) += blk.o
 obj-$(CONFIG_BOARD) += board.o
@@ -31,6 +32,7 @@
 obj-$(CONFIG_DM_MAILBOX) += mailbox.o
 obj-$(CONFIG_DM_MMC) += mmc.o
 obj-y += ofnode.o
+obj-y += fdtdec.o
 obj-$(CONFIG_OSD) += osd.o
 obj-$(CONFIG_DM_VIDEO) += panel.o
 obj-$(CONFIG_DM_PCI) += pci.o
diff --git a/test/dm/acpi.c b/test/dm/acpi.c
new file mode 100644
index 0000000..e7b8abd
--- /dev/null
+++ b/test/dm/acpi.c
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Tests for ACPI table generation
+ *
+ * Copyright 2019 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <acpi/acpi_table.h>
+#include <dm/acpi.h>
+#include <dm/test.h>
+#include <test/ut.h>
+
+#define ACPI_TEST_DEV_NAME	"ABCD"
+
+static int testacpi_get_name(const struct udevice *dev, char *out_name)
+{
+	return acpi_copy_name(out_name, ACPI_TEST_DEV_NAME);
+}
+
+struct acpi_ops testacpi_ops = {
+	.get_name	= testacpi_get_name,
+};
+
+static const struct udevice_id testacpi_ids[] = {
+	{ .compatible = "denx,u-boot-acpi-test" },
+	{ }
+};
+
+U_BOOT_DRIVER(testacpi_drv) = {
+	.name	= "testacpi_drv",
+	.of_match	= testacpi_ids,
+	.id	= UCLASS_TEST_ACPI,
+	ACPI_OPS_PTR(&testacpi_ops)
+};
+
+UCLASS_DRIVER(testacpi) = {
+	.name		= "testacpi",
+	.id		= UCLASS_TEST_ACPI,
+};
+
+/* Test ACPI get_name() */
+static int dm_test_acpi_get_name(struct unit_test_state *uts)
+{
+	char name[ACPI_NAME_MAX];
+	struct udevice *dev;
+
+	ut_assertok(uclass_first_device_err(UCLASS_TEST_ACPI, &dev));
+	ut_assertok(acpi_get_name(dev, name));
+	ut_asserteq_str(ACPI_TEST_DEV_NAME, name);
+
+	return 0;
+}
+DM_TEST(dm_test_acpi_get_name, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test acpi_get_table_revision() */
+static int dm_test_acpi_get_table_revision(struct unit_test_state *uts)
+{
+	ut_asserteq(1, acpi_get_table_revision(ACPITAB_MCFG));
+	ut_asserteq(2, acpi_get_table_revision(ACPITAB_RSDP));
+	ut_asserteq(4, acpi_get_table_revision(ACPITAB_TPM2));
+	ut_asserteq(-EINVAL, acpi_get_table_revision(ACPITAB_COUNT));
+
+	return 0;
+}
+DM_TEST(dm_test_acpi_get_table_revision,
+	DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Temporary change to ensure bisectability */
+#ifndef CONFIG_SANDBOX
+/* Test acpi_create_dmar() */
+static int dm_test_acpi_create_dmar(struct unit_test_state *uts)
+{
+	struct acpi_dmar dmar;
+
+	ut_assertok(acpi_create_dmar(&dmar, DMAR_INTR_REMAP));
+	ut_asserteq(DMAR_INTR_REMAP, dmar.flags);
+	ut_asserteq(32 - 1, dmar.host_address_width);
+
+	return 0;
+}
+DM_TEST(dm_test_acpi_create_dmar, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+#endif
diff --git a/test/dm/cpu.c b/test/dm/cpu.c
index f5f1cae..e6dc576 100644
--- a/test/dm/cpu.c
+++ b/test/dm/cpu.c
@@ -33,6 +33,7 @@
 	ut_assertok(cpu_get_info(dev, &info));
 	ut_asserteq(info.cpu_freq, 42 * 42 * 42 * 42 * 42);
 	ut_asserteq(info.features, 0x42424242);
+	ut_asserteq(info.address_width, 32);
 
 	ut_asserteq(cpu_get_count(dev), 42);
 
diff --git a/test/dm/fdtdec.c b/test/dm/fdtdec.c
new file mode 100644
index 0000000..b2f75b5
--- /dev/null
+++ b/test/dm/fdtdec.c
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2020 NXP
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/of_extra.h>
+#include <dm/test.h>
+#include <test/ut.h>
+
+static int dm_test_fdtdec_set_carveout(struct unit_test_state *uts)
+{
+	struct fdt_memory resv;
+	void *blob;
+	const fdt32_t *prop;
+	int blob_sz, len, offset;
+
+	blob_sz = fdt_totalsize(gd->fdt_blob) + 4096;
+	blob = malloc(blob_sz);
+	ut_assertnonnull(blob);
+
+	/* Make a writtable copy of the fdt blob */
+	ut_assertok(fdt_open_into(gd->fdt_blob, blob, blob_sz));
+
+	resv.start = 0x1000;
+	resv.end = 0x2000;
+	ut_assertok(fdtdec_set_carveout(blob, "/a-test",
+					"memory-region", 2, "test_resv1",
+					&resv));
+
+	resv.start = 0x10000;
+	resv.end = 0x20000;
+	ut_assertok(fdtdec_set_carveout(blob, "/a-test",
+					"memory-region", 1, "test_resv2",
+					&resv));
+
+	resv.start = 0x100000;
+	resv.end = 0x200000;
+	ut_assertok(fdtdec_set_carveout(blob, "/a-test",
+					"memory-region", 0, "test_resv3",
+					&resv));
+
+	offset = fdt_path_offset(blob, "/a-test");
+	ut_assert(offset > 0);
+	prop = fdt_getprop(blob, offset, "memory-region", &len);
+	ut_assertnonnull(prop);
+
+	ut_asserteq(len, 12);
+	ut_assert(fdt_node_offset_by_phandle(blob, fdt32_to_cpu(prop[0])) > 0);
+	ut_assert(fdt_node_offset_by_phandle(blob, fdt32_to_cpu(prop[1])) > 0);
+	ut_assert(fdt_node_offset_by_phandle(blob, fdt32_to_cpu(prop[2])) > 0);
+
+	free(blob);
+
+	return 0;
+}
+DM_TEST(dm_test_fdtdec_set_carveout,
+	DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT | DM_TESTF_FLAT_TREE);
diff --git a/test/dm/serial.c b/test/dm/serial.c
index 3d741a8..c6be6ab 100644
--- a/test/dm/serial.c
+++ b/test/dm/serial.c
@@ -29,6 +29,7 @@
 	ut_assertok(serial_getinfo(dev_serial, &info_serial));
 	ut_assert(info_serial.type == SERIAL_CHIP_UNKNOWN);
 	ut_assert(info_serial.addr == SERIAL_DEFAULT_ADDRESS);
+	ut_assert(info_serial.clock == SERIAL_DEFAULT_CLOCK);
 	/*
 	 * test with a parameter which is NULL pointer
 	 */
diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c
index 75ae080..a56275a 100644
--- a/test/dm/test-fdt.c
+++ b/test/dm/test-fdt.c
@@ -255,7 +255,7 @@
 	int ret;
 	int i;
 
-	ret = dm_scan_fdt(gd->fdt_blob, false);
+	ret = dm_extended_scan_fdt(gd->fdt_blob, false);
 	ut_assert(!ret);
 
 	ret = uclass_get(UCLASS_TEST_FDT, &uc);
@@ -867,6 +867,7 @@
 	u32 val32;
 	s32 sval;
 	uint val;
+	u64 val64;
 
 	ut_assertok(uclass_first_device_err(UCLASS_TEST_FDT, &dev));
 	ut_asserteq_str("a-test", dev->name);
@@ -891,10 +892,48 @@
 	ut_assertok(dev_read_u32u(dev, "uint-value", &val));
 	ut_asserteq(-1234, val);
 
+	ut_assertok(dev_read_u64(dev, "int64-value", &val64));
+	ut_asserteq_64(0x1111222233334444, val64);
+
+	ut_asserteq_64(-EINVAL, dev_read_u64(dev, "missing", &val64));
+	ut_asserteq_64(6, dev_read_u64_default(dev, "missing", 6));
+
+	ut_asserteq_64(0x1111222233334444,
+		       dev_read_u64_default(dev, "int64-value", 6));
+
 	return 0;
 }
 DM_TEST(dm_test_read_int, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
 
+static int dm_test_read_int_index(struct unit_test_state *uts)
+{
+	struct udevice *dev;
+	u32 val32;
+
+	ut_assertok(uclass_first_device_err(UCLASS_TEST_FDT, &dev));
+	ut_asserteq_str("a-test", dev->name);
+
+	ut_asserteq(-EINVAL, dev_read_u32_index(dev, "missing", 0, &val32));
+	ut_asserteq(19, dev_read_u32_index_default(dev, "missing", 0, 19));
+
+	ut_assertok(dev_read_u32_index(dev, "int-array", 0, &val32));
+	ut_asserteq(5678, val32);
+	ut_assertok(dev_read_u32_index(dev, "int-array", 1, &val32));
+	ut_asserteq(9123, val32);
+	ut_assertok(dev_read_u32_index(dev, "int-array", 2, &val32));
+	ut_asserteq(4567, val32);
+	ut_asserteq(-EOVERFLOW, dev_read_u32_index(dev, "int-array", 3,
+						   &val32));
+
+	ut_asserteq(5678, dev_read_u32_index_default(dev, "int-array", 0, 2));
+	ut_asserteq(9123, dev_read_u32_index_default(dev, "int-array", 1, 2));
+	ut_asserteq(4567, dev_read_u32_index_default(dev, "int-array", 2, 2));
+	ut_asserteq(2, dev_read_u32_index_default(dev, "int-array", 3, 2));
+
+	return 0;
+}
+DM_TEST(dm_test_read_int_index, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
 /* Test iteration through devices by drvdata */
 static int dm_test_uclass_drvdata(struct unit_test_state *uts)
 {
@@ -953,3 +992,28 @@
 	return 0;
 }
 DM_TEST(dm_test_first_child_probe, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test that ofdata is read for parents before children */
+static int dm_test_ofdata_order(struct unit_test_state *uts)
+{
+	struct udevice *bus, *dev;
+
+	ut_assertok(uclass_find_first_device(UCLASS_I2C, &bus));
+	ut_assertnonnull(bus);
+	ut_assert(!(bus->flags & DM_FLAG_PLATDATA_VALID));
+
+	ut_assertok(device_find_first_child(bus, &dev));
+	ut_assertnonnull(dev);
+	ut_assert(!(dev->flags & DM_FLAG_PLATDATA_VALID));
+
+	/* read the child's ofdata which should cause the parent's to be read */
+	ut_assertok(device_ofdata_to_platdata(dev));
+	ut_assert(dev->flags & DM_FLAG_PLATDATA_VALID);
+	ut_assert(bus->flags & DM_FLAG_PLATDATA_VALID);
+
+	ut_assert(!(dev->flags & DM_FLAG_ACTIVATED));
+	ut_assert(!(bus->flags & DM_FLAG_ACTIVATED));
+
+	return 0;
+}
+DM_TEST(dm_test_ofdata_order, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
diff --git a/test/log/Makefile b/test/log/Makefile
index e0d0a47..4c92550 100644
--- a/test/log/Makefile
+++ b/test/log/Makefile
@@ -3,3 +3,17 @@
 # Copyright (c) 2017 Google, Inc
 
 obj-$(CONFIG_LOG_TEST) += log_test.o
+
+ifdef CONFIG_UT_LOG
+
+obj-y += test-main.o
+
+ifdef CONFIG_SANDBOX
+obj-$(CONFIG_LOG_SYSLOG) += syslog_test.o
+endif
+
+ifndef CONFIG_LOG
+obj-$(CONFIG_CONSOLE_RECORD) += nolog_test.o
+endif
+
+endif # CONFIG_UT_LOG
diff --git a/test/log/nolog_test.c b/test/log/nolog_test.c
new file mode 100644
index 0000000..8461952
--- /dev/null
+++ b/test/log/nolog_test.c
@@ -0,0 +1,135 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2020, Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * Logging function tests for CONFIG_LOG=n.
+ */
+
+/* Needed for testing log_debug() */
+#define DEBUG 1
+
+#include <common.h>
+#include <console.h>
+#include <test/log.h>
+#include <test/test.h>
+#include <test/suites.h>
+#include <test/ut.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define BUFFSIZE 32
+
+static int nolog_test_log_err(struct unit_test_state *uts)
+{
+	char buf[BUFFSIZE];
+
+	memset(buf, 0, BUFFSIZE);
+	console_record_reset_enable();
+	log_err("testing %s\n", "log_err");
+	gd->flags &= ~GD_FLG_RECORD;
+	ut_assertok(ut_check_console_line(uts, "testing log_err"));
+	ut_assertok(ut_check_console_end(uts));
+	return 0;
+}
+LOG_TEST(nolog_test_log_err);
+
+static int nolog_test_log_warning(struct unit_test_state *uts)
+{
+	char buf[BUFFSIZE];
+
+	memset(buf, 0, BUFFSIZE);
+	console_record_reset_enable();
+	log_warning("testing %s\n", "log_warning");
+	gd->flags &= ~GD_FLG_RECORD;
+	ut_assertok(ut_check_console_line(uts, "testing log_warning"));
+	ut_assertok(ut_check_console_end(uts));
+	return 0;
+}
+LOG_TEST(nolog_test_log_warning);
+
+static int nolog_test_log_notice(struct unit_test_state *uts)
+{
+	char buf[BUFFSIZE];
+
+	memset(buf, 0, BUFFSIZE);
+	console_record_reset_enable();
+	log_notice("testing %s\n", "log_notice");
+	gd->flags &= ~GD_FLG_RECORD;
+	ut_assertok(ut_check_console_line(uts, "testing log_notice"));
+	ut_assertok(ut_check_console_end(uts));
+	return 0;
+}
+LOG_TEST(nolog_test_log_notice);
+
+static int nolog_test_log_info(struct unit_test_state *uts)
+{
+	char buf[BUFFSIZE];
+
+	memset(buf, 0, BUFFSIZE);
+	console_record_reset_enable();
+	log_err("testing %s\n", "log_info");
+	gd->flags &= ~GD_FLG_RECORD;
+	ut_assertok(ut_check_console_line(uts, "testing log_info"));
+	ut_assertok(ut_check_console_end(uts));
+	return 0;
+}
+LOG_TEST(nolog_test_log_info);
+
+#undef _DEBUG
+#define _DEBUG 0
+static int nolog_test_nodebug(struct unit_test_state *uts)
+{
+	char buf[BUFFSIZE];
+
+	memset(buf, 0, BUFFSIZE);
+	console_record_reset_enable();
+	debug("testing %s\n", "debug");
+	gd->flags &= ~GD_FLG_RECORD;
+	ut_assertok(ut_check_console_end(uts));
+	return 0;
+}
+LOG_TEST(nolog_test_nodebug);
+
+static int nolog_test_log_nodebug(struct unit_test_state *uts)
+{
+	char buf[BUFFSIZE];
+
+	memset(buf, 0, BUFFSIZE);
+	console_record_reset_enable();
+	log_debug("testing %s\n", "log_debug");
+	gd->flags &= ~GD_FLG_RECORD;
+	ut_assert(!strcmp(buf, ""));
+	ut_assertok(ut_check_console_end(uts));
+	return 0;
+}
+LOG_TEST(nolog_test_log_nodebug);
+
+#undef _DEBUG
+#define _DEBUG 1
+static int nolog_test_debug(struct unit_test_state *uts)
+{
+	char buf[BUFFSIZE];
+
+	memset(buf, 0, BUFFSIZE);
+	console_record_reset_enable();
+	debug("testing %s\n", "debug");
+	gd->flags &= ~GD_FLG_RECORD;
+	ut_assertok(ut_check_console_line(uts, "testing debug"));
+	ut_assertok(ut_check_console_end(uts));
+	return 0;
+}
+LOG_TEST(nolog_test_debug);
+
+static int nolog_test_log_debug(struct unit_test_state *uts)
+{
+	char buf[BUFFSIZE];
+
+	memset(buf, 0, BUFFSIZE);
+	console_record_reset_enable();
+	log_debug("testing %s\n", "log_debug");
+	gd->flags &= ~GD_FLG_RECORD;
+	ut_assertok(ut_check_console_line(uts, "testing log_debug"));
+	ut_assertok(ut_check_console_end(uts));
+	return 0;
+}
+LOG_TEST(nolog_test_log_debug);
diff --git a/test/log/syslog_test.c b/test/log/syslog_test.c
new file mode 100644
index 0000000..6ca5760
--- /dev/null
+++ b/test/log/syslog_test.c
@@ -0,0 +1,280 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2020, Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * Logging function tests for CONFIG_LOG_SYSLOG=y.
+ *
+ * Invoke the test with: ./u-boot -d arch/sandbox/dts/test.dtb
+ */
+
+/* Override CONFIG_LOG_MAX_LEVEL */
+#define LOG_DEBUG
+
+#include <common.h>
+#include <dm/device.h>
+#include <hexdump.h>
+#include <test/log.h>
+#include <test/test.h>
+#include <test/suites.h>
+#include <test/ut.h>
+#include <asm/eth.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/**
+ * struct sb_log_env - private data for sandbox ethernet driver
+ *
+ * This structure is used for the private data of the sandbox ethernet
+ * driver.
+ *
+ * @expected:	string expected to be written by the syslog driver
+ * @uts:	unit test state
+ */
+struct sb_log_env {
+	const char *expected;
+	struct unit_test_state *uts;
+};
+
+/**
+ * sb_log_tx_handler() - transmit callback function
+ *
+ * This callback function is invoked when a network package is sent using the
+ * sandbox Ethernet driver. The private data of the driver holds a sb_log_env
+ * structure with the unit test state and the expected UDP payload.
+ *
+ * The following checks are executed:
+ *
+ * * the Ethernet packet indicates a IP broadcast message
+ * * the IP header is for a local UDP broadcast message to port 514
+ * * the UDP payload matches the expected string
+ *
+ * After testing the pointer to the expected string is set to NULL to signal
+ * that the callback function has been called.
+ *
+ * @dev:	sandbox ethernet device
+ * @packet:	Ethernet packet
+ * @len:	length of Ethernet packet
+ * Return:	0 = success
+ */
+static int sb_log_tx_handler(struct udevice *dev, void *packet,
+			     unsigned int len)
+{
+	struct eth_sandbox_priv *priv = dev_get_priv(dev);
+	struct sb_log_env *env = priv->priv;
+	/* uts is updated by the ut_assert* macros */
+	struct unit_test_state *uts = env->uts;
+	char *buf = packet;
+	struct ethernet_hdr *eth_hdr = packet;
+	struct ip_udp_hdr *ip_udp_hdr;
+
+	/* Check Ethernet header */
+	ut_asserteq_mem(&eth_hdr->et_dest, net_bcast_ethaddr, ARP_HLEN);
+	ut_asserteq(ntohs(eth_hdr->et_protlen), PROT_IP);
+
+	/* Check IP header */
+	buf += sizeof(struct ethernet_hdr);
+	ip_udp_hdr = (struct ip_udp_hdr *)buf;
+	ut_asserteq(ip_udp_hdr->ip_p, IPPROTO_UDP);
+	ut_asserteq(ip_udp_hdr->ip_dst.s_addr, 0xffffffff);
+	ut_asserteq(ntohs(ip_udp_hdr->udp_dst), 514);
+	ut_asserteq(UDP_HDR_SIZE + strlen(env->expected) + 1,
+		    ntohs(ip_udp_hdr->udp_len));
+
+	/* Check payload */
+	buf += sizeof(struct ip_udp_hdr);
+	ut_asserteq_mem(env->expected, buf,
+			ntohs(ip_udp_hdr->udp_len) - UDP_HDR_SIZE);
+
+	/* Signal that the callback function has been executed */
+	env->expected = NULL;
+
+	return 0;
+}
+
+/**
+ * syslog_test_log_err() - test log_err() function
+ *
+ * @uts:	unit test state
+ * Return:	0 = success
+ */
+static int syslog_test_log_err(struct unit_test_state *uts)
+{
+	int old_log_level = gd->default_log_level;
+	struct sb_log_env env;
+
+	gd->log_fmt = LOGF_DEFAULT;
+	gd->default_log_level = LOGL_INFO;
+	env_set("ethact", "eth@10002000");
+	env_set("log_hostname", "sandbox");
+	env.expected = "<3>sandbox uboot: syslog_test_log_err() "
+		       "testing log_err\n";
+	env.uts = uts;
+	sandbox_eth_set_tx_handler(0, sb_log_tx_handler);
+	/* Used by ut_assert macros in the tx_handler */
+	sandbox_eth_set_priv(0, &env);
+	log_err("testing %s\n", "log_err");
+	/* Check that the callback function was called */
+	sandbox_eth_set_tx_handler(0, NULL);
+	gd->default_log_level = old_log_level;
+
+	return 0;
+}
+LOG_TEST(syslog_test_log_err);
+
+/**
+ * syslog_test_log_warning() - test log_warning() function
+ *
+ * @uts:	unit test state
+ * Return:	0 = success
+ */
+static int syslog_test_log_warning(struct unit_test_state *uts)
+{
+	int old_log_level = gd->default_log_level;
+	struct sb_log_env env;
+
+	gd->log_fmt = LOGF_DEFAULT;
+	gd->default_log_level = LOGL_INFO;
+	env_set("ethact", "eth@10002000");
+	env_set("log_hostname", "sandbox");
+	env.expected = "<4>sandbox uboot: syslog_test_log_warning() "
+		       "testing log_warning\n";
+	env.uts = uts;
+	sandbox_eth_set_tx_handler(0, sb_log_tx_handler);
+	/* Used by ut_assert macros in the tx_handler */
+	sandbox_eth_set_priv(0, &env);
+	log_warning("testing %s\n", "log_warning");
+	sandbox_eth_set_tx_handler(0, NULL);
+	/* Check that the callback function was called */
+	ut_assertnull(env.expected);
+	gd->default_log_level = old_log_level;
+
+	return 0;
+}
+LOG_TEST(syslog_test_log_warning);
+
+/**
+ * syslog_test_log_notice() - test log_notice() function
+ *
+ * @uts:	unit test state
+ * Return:	0 = success
+ */
+static int syslog_test_log_notice(struct unit_test_state *uts)
+{
+	int old_log_level = gd->default_log_level;
+	struct sb_log_env env;
+
+	gd->log_fmt = LOGF_DEFAULT;
+	gd->default_log_level = LOGL_INFO;
+	env_set("ethact", "eth@10002000");
+	env_set("log_hostname", "sandbox");
+	env.expected = "<5>sandbox uboot: syslog_test_log_notice() "
+		       "testing log_notice\n";
+	env.uts = uts;
+	sandbox_eth_set_tx_handler(0, sb_log_tx_handler);
+	/* Used by ut_assert macros in the tx_handler */
+	sandbox_eth_set_priv(0, &env);
+	log_notice("testing %s\n", "log_notice");
+	sandbox_eth_set_tx_handler(0, NULL);
+	/* Check that the callback function was called */
+	ut_assertnull(env.expected);
+	gd->default_log_level = old_log_level;
+
+	return 0;
+}
+LOG_TEST(syslog_test_log_notice);
+
+/**
+ * syslog_test_log_info() - test log_info() function
+ *
+ * @uts:	unit test state
+ * Return:	0 = success
+ */
+static int syslog_test_log_info(struct unit_test_state *uts)
+{
+	int old_log_level = gd->default_log_level;
+	struct sb_log_env env;
+
+	gd->log_fmt = LOGF_DEFAULT;
+	gd->default_log_level = LOGL_INFO;
+	env_set("ethact", "eth@10002000");
+	env_set("log_hostname", "sandbox");
+	env.expected = "<6>sandbox uboot: syslog_test_log_info() "
+		       "testing log_info\n";
+	env.uts = uts;
+	sandbox_eth_set_tx_handler(0, sb_log_tx_handler);
+	/* Used by ut_assert macros in the tx_handler */
+	sandbox_eth_set_priv(0, &env);
+	log_info("testing %s\n", "log_info");
+	sandbox_eth_set_tx_handler(0, NULL);
+	/* Check that the callback function was called */
+	ut_assertnull(env.expected);
+	gd->default_log_level = old_log_level;
+
+	return 0;
+}
+LOG_TEST(syslog_test_log_info);
+
+/**
+ * syslog_test_log_debug() - test log_debug() function
+ *
+ * @uts:	unit test state
+ * Return:	0 = success
+ */
+static int syslog_test_log_debug(struct unit_test_state *uts)
+{
+	int old_log_level = gd->default_log_level;
+	struct sb_log_env env;
+
+	gd->log_fmt = LOGF_DEFAULT;
+	gd->default_log_level = LOGL_DEBUG;
+	env_set("ethact", "eth@10002000");
+	env_set("log_hostname", "sandbox");
+	env.expected = "<7>sandbox uboot: syslog_test_log_debug() "
+		       "testing log_debug\n";
+	env.uts = uts;
+	sandbox_eth_set_tx_handler(0, sb_log_tx_handler);
+	/* Used by ut_assert macros in the tx_handler */
+	sandbox_eth_set_priv(0, &env);
+	log_debug("testing %s\n", "log_debug");
+	sandbox_eth_set_tx_handler(0, NULL);
+	/* Check that the callback function was called */
+	ut_assertnull(env.expected);
+	gd->default_log_level = old_log_level;
+
+	return 0;
+}
+LOG_TEST(syslog_test_log_debug);
+
+/**
+ * syslog_test_log_nodebug() - test logging level filter
+ *
+ * Verify that log_debug() does not lead to a log message if the logging level
+ * is set to LOGL_INFO.
+ *
+ * @uts:	unit test state
+ * Return:	0 = success
+ */
+static int syslog_test_log_nodebug(struct unit_test_state *uts)
+{
+	int old_log_level = gd->default_log_level;
+	struct sb_log_env env;
+
+	gd->log_fmt = LOGF_DEFAULT;
+	gd->default_log_level = LOGL_INFO;
+	env_set("ethact", "eth@10002000");
+	env_set("log_hostname", "sandbox");
+	env.expected = "<7>sandbox uboot: syslog_test_log_nodebug() "
+		       "testing log_debug\n";
+	env.uts = uts;
+	sandbox_eth_set_tx_handler(0, sb_log_tx_handler);
+	/* Used by ut_assert macros in the tx_handler */
+	sandbox_eth_set_priv(0, &env);
+	log_debug("testing %s\n", "log_debug");
+	sandbox_eth_set_tx_handler(0, NULL);
+	/* Check that the callback function was not called */
+	ut_assertnonnull(env.expected);
+	gd->default_log_level = old_log_level;
+
+	return 0;
+}
+LOG_TEST(syslog_test_log_nodebug);
diff --git a/test/log/test-main.c b/test/log/test-main.c
new file mode 100644
index 0000000..855de47
--- /dev/null
+++ b/test/log/test-main.c
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2020, Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * Logging function tests.
+ */
+
+#include <common.h>
+#include <console.h>
+#include <test/log.h>
+#include <test/suites.h>
+
+int do_ut_log(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	struct unit_test *tests = ll_entry_start(struct unit_test, log_test);
+	const int n_ents = ll_entry_count(struct unit_test, log_test);
+
+	return cmd_ut_category("log", "log_test_",
+			       tests, n_ents, argc, argv);
+}
diff --git a/tools/patman/series.py b/tools/patman/series.py
index a15f762..6d9d48b 100644
--- a/tools/patman/series.py
+++ b/tools/patman/series.py
@@ -249,8 +249,10 @@
         if cover_fname:
             cover_cc = gitutil.BuildEmailList(self.get('cover_cc', ''))
             cover_cc = [tools.FromUnicode(m) for m in cover_cc]
-            cc_list = '\0'.join([tools.ToUnicode(x)
-                                 for x in sorted(set(cover_cc + all_ccs))])
+            cover_cc = list(set(cover_cc + all_ccs))
+            if limit is not None:
+                cover_cc = cover_cc[:limit]
+            cc_list = '\0'.join([tools.ToUnicode(x) for x in sorted(cover_cc)])
             print(cover_fname, cc_list, file=fd)
 
         fd.close()