From 1ac10ab9d73ea8d39dc93fbf8f993267ec8f9041 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Tue, 3 Jul 2018 02:48:39 -0700 Subject: [PATCH 01/10] x86: quark: acpi: Add full reset bit to the reset register value in FADT This adds full reset bit in the reset register value in the ACPI FADT table, so that kernel can do a thorough reboot. Signed-off-by: Bin Meng Reviewed-by: Simon Glass --- arch/x86/cpu/quark/acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/cpu/quark/acpi.c b/arch/x86/cpu/quark/acpi.c index 4a0272085c..7b6fc2f4a5 100644 --- a/arch/x86/cpu/quark/acpi.c +++ b/arch/x86/cpu/quark/acpi.c @@ -67,7 +67,7 @@ void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs, fadt->reset_reg.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS; fadt->reset_reg.addrl = IO_PORT_RESET; fadt->reset_reg.addrh = 0; - fadt->reset_value = SYS_RST | RST_CPU; + fadt->reset_value = SYS_RST | RST_CPU | FULL_RST; fadt->x_firmware_ctl_l = (u32)facs; fadt->x_firmware_ctl_h = 0; From fabb2b4c7f28e672080a97980c4bb1a45375cbb3 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Tue, 3 Jul 2018 02:48:40 -0700 Subject: [PATCH 02/10] dm: sysreset: x86: Add a sysreset driver This adds a generic reset driver for x86 processor. Signed-off-by: Bin Meng Reviewed-by: Simon Glass --- drivers/sysreset/Kconfig | 6 ++++ drivers/sysreset/Makefile | 1 + drivers/sysreset/sysreset_x86.c | 49 +++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 drivers/sysreset/sysreset_x86.c diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig index f2524c18b7..9b2fda4d25 100644 --- a/drivers/sysreset/Kconfig +++ b/drivers/sysreset/Kconfig @@ -51,4 +51,10 @@ config SYSRESET_WATCHDOG help Reboot support for generic watchdog reset. +config SYSRESET_X86 + bool "Enable support for x86 processor reboot driver" + depends on X86 + help + Reboot support for generic x86 processor reset. + endmenu diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile index 223a0716f0..707f1d7469 100644 --- a/drivers/sysreset/Makefile +++ b/drivers/sysreset/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_SYSRESET_MICROBLAZE) += sysreset_microblaze.o obj-$(CONFIG_SYSRESET_PSCI) += sysreset_psci.o obj-$(CONFIG_SYSRESET_SYSCON) += sysreset_syscon.o obj-$(CONFIG_SYSRESET_WATCHDOG) += sysreset_watchdog.o +obj-$(CONFIG_SYSRESET_X86) += sysreset_x86.o obj-$(CONFIG_ARCH_ROCKCHIP) += sysreset_rockchip.o obj-$(CONFIG_SANDBOX) += sysreset_sandbox.o obj-$(CONFIG_ARCH_STI) += sysreset_sti.o diff --git a/drivers/sysreset/sysreset_x86.c b/drivers/sysreset/sysreset_x86.c new file mode 100644 index 0000000000..5943a63854 --- /dev/null +++ b/drivers/sysreset/sysreset_x86.c @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018, Bin Meng + * + * Generic reset driver for x86 processor + */ + +#include +#include +#include +#include +#include + +static int x86_sysreset_request(struct udevice *dev, enum sysreset_t type) +{ + int value; + + switch (type) { + case SYSRESET_WARM: + value = SYS_RST | RST_CPU; + break; + case SYSRESET_COLD: + value = SYS_RST | RST_CPU | FULL_RST; + break; + default: + return -ENOSYS; + } + + outb(value, IO_PORT_RESET); + + return -EINPROGRESS; +} + +static const struct udevice_id x86_sysreset_ids[] = { + { .compatible = "x86,reset" }, + { } +}; + +static struct sysreset_ops x86_sysreset_ops = { + .request = x86_sysreset_request, +}; + +U_BOOT_DRIVER(x86_sysreset) = { + .name = "x86-sysreset", + .id = UCLASS_SYSRESET, + .of_match = x86_sysreset_ids, + .ops = &x86_sysreset_ops, + .flags = DM_FLAG_PRE_RELOC, +}; From c81a8f54553a31925d4d26435bd104543bbe85af Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 19 Jul 2018 03:07:29 -0700 Subject: [PATCH 03/10] efi: app: Add a sysreset driver This adds the DM sysreset driver for EFI application support. Signed-off-by: Bin Meng Reviewed-by: Simon Glass --- lib/efi/efi_app.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/lib/efi/efi_app.c b/lib/efi/efi_app.c index 3eb8eeb677..5879d40386 100644 --- a/lib/efi/efi_app.c +++ b/lib/efi/efi_app.c @@ -10,11 +10,13 @@ #include #include +#include #include #include #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -129,7 +131,7 @@ efi_status_t EFIAPI efi_main(efi_handle_t image, return EFI_SUCCESS; } -void reset_cpu(ulong addr) +static void efi_exit(void) { struct efi_priv *priv = global_priv; @@ -137,3 +139,27 @@ void reset_cpu(ulong addr) printf("U-Boot EFI exiting\n"); priv->boot->exit(priv->parent_image, EFI_SUCCESS, 0, NULL); } + +static int efi_sysreset_request(struct udevice *dev, enum sysreset_t type) +{ + efi_exit(); + + return -EINPROGRESS; +} + +static const struct udevice_id efi_sysreset_ids[] = { + { .compatible = "efi,reset" }, + { } +}; + +static struct sysreset_ops efi_sysreset_ops = { + .request = efi_sysreset_request, +}; + +U_BOOT_DRIVER(efi_sysreset) = { + .name = "efi-sysreset", + .id = UCLASS_SYSRESET, + .of_match = efi_sysreset_ids, + .ops = &efi_sysreset_ops, + .flags = DM_FLAG_PRE_RELOC, +}; From 4c99ccfe13e8f1a1d3cf5be567fa16e2aa68188e Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 19 Jul 2018 03:07:30 -0700 Subject: [PATCH 04/10] x86: tangier: Add a sysreset driver This adds a reset driver for tangier processor. Signed-off-by: Bin Meng Reviewed-by: Simon Glass Tested-by: Andy Shevchenko --- arch/x86/cpu/tangier/Makefile | 2 +- arch/x86/cpu/tangier/sysreset.c | 48 +++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 arch/x86/cpu/tangier/sysreset.c diff --git a/arch/x86/cpu/tangier/Makefile b/arch/x86/cpu/tangier/Makefile index 44ccb3ff91..827448257e 100644 --- a/arch/x86/cpu/tangier/Makefile +++ b/arch/x86/cpu/tangier/Makefile @@ -2,5 +2,5 @@ # # Copyright (c) 2017 Intel Corporation -obj-y += car.o tangier.o sdram.o +obj-y += car.o tangier.o sdram.o sysreset.o obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi.o diff --git a/arch/x86/cpu/tangier/sysreset.c b/arch/x86/cpu/tangier/sysreset.c new file mode 100644 index 0000000000..e762ee1b81 --- /dev/null +++ b/arch/x86/cpu/tangier/sysreset.c @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018, Bin Meng + * + * Reset driver for tangier processor + */ + +#include +#include +#include +#include + +static int tangier_sysreset_request(struct udevice *dev, enum sysreset_t type) +{ + int value; + + switch (type) { + case SYSRESET_WARM: + value = IPCMSG_WARM_RESET; + break; + case SYSRESET_COLD: + value = IPCMSG_COLD_RESET; + break; + default: + return -ENOSYS; + } + + scu_ipc_simple_command(value, 0); + + return -EINPROGRESS; +} + +static const struct udevice_id tangier_sysreset_ids[] = { + { .compatible = "intel,reset-tangier" }, + { } +}; + +static struct sysreset_ops tangier_sysreset_ops = { + .request = tangier_sysreset_request, +}; + +U_BOOT_DRIVER(tangier_sysreset) = { + .name = "tangier-sysreset", + .id = UCLASS_SYSRESET, + .of_match = tangier_sysreset_ids, + .ops = &tangier_sysreset_ops, + .flags = DM_FLAG_PRE_RELOC, +}; From 406be398ed2671875a6297ff2c5a4f05a00e0cff Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 19 Jul 2018 03:07:31 -0700 Subject: [PATCH 05/10] dm: sysreset: Add a standard message when doing reset It's good to print a message when doing reset. Signed-off-by: Bin Meng Reviewed-by: Simon Glass --- drivers/sysreset/sysreset-uclass.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/sysreset/sysreset-uclass.c b/drivers/sysreset/sysreset-uclass.c index 840eab6b57..b918365e73 100644 --- a/drivers/sysreset/sysreset-uclass.c +++ b/drivers/sysreset/sysreset-uclass.c @@ -69,6 +69,8 @@ void reset_cpu(ulong addr) int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { + printf("resetting ...\n"); + sysreset_walk_halt(SYSRESET_COLD); return 0; From 7bb6028768c31bf454314b622f52235fb7d82764 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 19 Jul 2018 03:07:32 -0700 Subject: [PATCH 06/10] x86: fsp: Eliminate the reset_cpu() call In preparation for the reset driver conversion, eliminate the reset_cpu() call in the FSP init path as it's too early for the reset driver to work. Signed-off-by: Bin Meng Reviewed-by: Simon Glass --- arch/x86/lib/fsp/fsp_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/lib/fsp/fsp_common.c b/arch/x86/lib/fsp/fsp_common.c index b4ba129725..d5ed1d5631 100644 --- a/arch/x86/lib/fsp/fsp_common.c +++ b/arch/x86/lib/fsp/fsp_common.c @@ -132,7 +132,7 @@ int arch_fsp_init(void) chipset_clear_sleep_state(); /* Reboot */ debug("Rebooting..\n"); - reset_cpu(0); + outb(SYS_RST | RST_CPU, IO_PORT_RESET); /* Should not reach here.. */ panic("Reboot System"); } From b37b7b2063e02718970ca1882a4522ccbe1106e9 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 19 Jul 2018 03:07:33 -0700 Subject: [PATCH 07/10] x86: Switch to use DM sysreset driver This converts all x86 boards over to DM sysreset. Signed-off-by: Bin Meng Reviewed-by: Simon Glass Tested-by: Andy Shevchenko --- arch/Kconfig | 2 ++ arch/x86/cpu/baytrail/valleyview.c | 6 ----- arch/x86/cpu/braswell/braswell.c | 6 ----- arch/x86/cpu/cpu.c | 26 ------------------- arch/x86/cpu/ivybridge/early_me.c | 7 ++--- arch/x86/cpu/ivybridge/sdram.c | 3 ++- arch/x86/cpu/qemu/qemu.c | 6 ----- arch/x86/cpu/quark/quark.c | 6 ----- arch/x86/cpu/tangier/tangier.c | 6 ----- arch/x86/dts/bayleybay.dts | 1 + arch/x86/dts/baytrail_som-db5800-som-6867.dts | 1 + arch/x86/dts/broadwell_som-6896.dts | 1 + arch/x86/dts/cherryhill.dts | 1 + arch/x86/dts/chromebook_link.dts | 1 + arch/x86/dts/chromebook_samus.dts | 1 + arch/x86/dts/chromebox_panther.dts | 1 + arch/x86/dts/conga-qeval20-qa3-e3845.dts | 1 + arch/x86/dts/cougarcanyon2.dts | 1 + arch/x86/dts/crownbay.dts | 1 + arch/x86/dts/dfi-bt700.dtsi | 1 + arch/x86/dts/edison.dts | 5 ++++ arch/x86/dts/efi-x86_app.dts | 5 ++++ arch/x86/dts/efi-x86_payload.dts | 1 + arch/x86/dts/galileo.dts | 1 + arch/x86/dts/minnowmax.dts | 1 + arch/x86/dts/qemu-x86_i440fx.dts | 1 + arch/x86/dts/qemu-x86_q35.dts | 1 + arch/x86/dts/reset.dtsi | 6 +++++ arch/x86/include/asm/processor.h | 5 ---- arch/x86/include/asm/u-boot-x86.h | 1 - configs/chromebook_link64_defconfig | 1 + 31 files changed, 41 insertions(+), 66 deletions(-) create mode 100644 arch/x86/dts/reset.dtsi diff --git a/arch/Kconfig b/arch/Kconfig index dd5a887001..cbeb9f6734 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -118,6 +118,8 @@ config X86 imply DM_SPI_FLASH imply DM_USB imply DM_VIDEO + imply SYSRESET + imply SYSRESET_X86 imply CMD_FPGA_LOADMK imply CMD_GETTIME imply CMD_IO diff --git a/arch/x86/cpu/baytrail/valleyview.c b/arch/x86/cpu/baytrail/valleyview.c index b7d481ac56..8882a76eae 100644 --- a/arch/x86/cpu/baytrail/valleyview.c +++ b/arch/x86/cpu/baytrail/valleyview.c @@ -55,9 +55,3 @@ int arch_misc_init(void) return 0; } - -void reset_cpu(ulong addr) -{ - /* cold reset */ - x86_full_reset(); -} diff --git a/arch/x86/cpu/braswell/braswell.c b/arch/x86/cpu/braswell/braswell.c index 32a6a5e5a8..7a83b06005 100644 --- a/arch/x86/cpu/braswell/braswell.c +++ b/arch/x86/cpu/braswell/braswell.c @@ -27,9 +27,3 @@ int arch_misc_init(void) return 0; } - -void reset_cpu(ulong addr) -{ - /* cold reset */ - x86_full_reset(); -} diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c index 6aefa12a7c..37615d055a 100644 --- a/arch/x86/cpu/cpu.c +++ b/arch/x86/cpu/cpu.c @@ -75,37 +75,11 @@ int x86_init_cache(void) } int init_cache(void) __attribute__((weak, alias("x86_init_cache"))); -int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - printf("resetting ...\n"); - - /* wait 50 ms */ - udelay(50000); - disable_interrupts(); - reset_cpu(0); - - /*NOTREACHED*/ - return 0; -} - void flush_cache(unsigned long dummy1, unsigned long dummy2) { asm("wbinvd\n"); } -__weak void reset_cpu(ulong addr) -{ - /* Do a hard reset through the chipset's reset control register */ - outb(SYS_RST | RST_CPU, IO_PORT_RESET); - for (;;) - cpu_hlt(); -} - -void x86_full_reset(void) -{ - outb(FULL_RST | SYS_RST | RST_CPU, IO_PORT_RESET); -} - /* Define these functions to allow ehch-hcd to function */ void flush_dcache_range(unsigned long start, unsigned long stop) { diff --git a/arch/x86/cpu/ivybridge/early_me.c b/arch/x86/cpu/ivybridge/early_me.c index 1a15229196..219d5be399 100644 --- a/arch/x86/cpu/ivybridge/early_me.c +++ b/arch/x86/cpu/ivybridge/early_me.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -138,17 +139,17 @@ int intel_early_me_init_done(struct udevice *dev, struct udevice *me_dev, case ME_HFS_ACK_RESET: /* Non-power cycle reset */ set_global_reset(dev, 0); - reset_cpu(0); + sysreset_walk_halt(SYSRESET_COLD); break; case ME_HFS_ACK_PWR_CYCLE: /* Power cycle reset */ set_global_reset(dev, 0); - x86_full_reset(); + sysreset_walk_halt(SYSRESET_COLD); break; case ME_HFS_ACK_GBL_RESET: /* Global reset */ set_global_reset(dev, 1); - x86_full_reset(); + sysreset_walk_halt(SYSRESET_COLD); break; case ME_HFS_ACK_S3: case ME_HFS_ACK_S4: diff --git a/arch/x86/cpu/ivybridge/sdram.c b/arch/x86/cpu/ivybridge/sdram.c index 2f253e813e..8a58d0383d 100644 --- a/arch/x86/cpu/ivybridge/sdram.c +++ b/arch/x86/cpu/ivybridge/sdram.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -497,7 +498,7 @@ int dram_init(void) /* If MRC data is not found we cannot continue S3 resume. */ if (pei_data->boot_mode == PEI_BOOT_RESUME && !pei_data->mrc_input) { debug("Giving up in sdram_initialize: No MRC data\n"); - reset_cpu(0); + sysreset_walk_halt(SYSRESET_COLD); } /* Pass console handler in pei_data */ diff --git a/arch/x86/cpu/qemu/qemu.c b/arch/x86/cpu/qemu/qemu.c index ca4b3f0833..5e8b4f068e 100644 --- a/arch/x86/cpu/qemu/qemu.c +++ b/arch/x86/cpu/qemu/qemu.c @@ -156,12 +156,6 @@ int print_cpuinfo(void) } #endif -void reset_cpu(ulong addr) -{ - /* cold reset */ - x86_full_reset(); -} - int arch_early_init_r(void) { qemu_chipset_init(); diff --git a/arch/x86/cpu/quark/quark.c b/arch/x86/cpu/quark/quark.c index 4fd686424d..d39edb2271 100644 --- a/arch/x86/cpu/quark/quark.c +++ b/arch/x86/cpu/quark/quark.c @@ -270,12 +270,6 @@ int print_cpuinfo(void) return default_print_cpuinfo(); } -void reset_cpu(ulong addr) -{ - /* cold reset */ - x86_full_reset(); -} - static void quark_pcie_init(void) { u32 val; diff --git a/arch/x86/cpu/tangier/tangier.c b/arch/x86/cpu/tangier/tangier.c index 0a15e64344..df2c600be3 100644 --- a/arch/x86/cpu/tangier/tangier.c +++ b/arch/x86/cpu/tangier/tangier.c @@ -4,7 +4,6 @@ */ #include -#include #include /* @@ -24,8 +23,3 @@ int print_cpuinfo(void) { return default_print_cpuinfo(); } - -void reset_cpu(ulong addr) -{ - scu_ipc_simple_command(IPCMSG_COLD_RESET, 0); -} diff --git a/arch/x86/dts/bayleybay.dts b/arch/x86/dts/bayleybay.dts index 74291a8f09..9683c525a7 100644 --- a/arch/x86/dts/bayleybay.dts +++ b/arch/x86/dts/bayleybay.dts @@ -12,6 +12,7 @@ /include/ "skeleton.dtsi" /include/ "keyboard.dtsi" /include/ "serial.dtsi" +/include/ "reset.dtsi" /include/ "rtc.dtsi" /include/ "tsc_timer.dtsi" /include/ "coreboot_fb.dtsi" diff --git a/arch/x86/dts/baytrail_som-db5800-som-6867.dts b/arch/x86/dts/baytrail_som-db5800-som-6867.dts index 36e6069b19..4e8a761ce8 100644 --- a/arch/x86/dts/baytrail_som-db5800-som-6867.dts +++ b/arch/x86/dts/baytrail_som-db5800-som-6867.dts @@ -12,6 +12,7 @@ /include/ "skeleton.dtsi" /include/ "serial.dtsi" +/include/ "reset.dtsi" /include/ "rtc.dtsi" /include/ "tsc_timer.dtsi" diff --git a/arch/x86/dts/broadwell_som-6896.dts b/arch/x86/dts/broadwell_som-6896.dts index 3966199085..ec691f136a 100644 --- a/arch/x86/dts/broadwell_som-6896.dts +++ b/arch/x86/dts/broadwell_som-6896.dts @@ -2,6 +2,7 @@ /include/ "skeleton.dtsi" /include/ "serial.dtsi" +/include/ "reset.dtsi" /include/ "rtc.dtsi" /include/ "tsc_timer.dtsi" /include/ "coreboot_fb.dtsi" diff --git a/arch/x86/dts/cherryhill.dts b/arch/x86/dts/cherryhill.dts index 3e29683bd9..39e2d2fa4b 100644 --- a/arch/x86/dts/cherryhill.dts +++ b/arch/x86/dts/cherryhill.dts @@ -10,6 +10,7 @@ /include/ "skeleton.dtsi" /include/ "serial.dtsi" +/include/ "reset.dtsi" /include/ "rtc.dtsi" /include/ "tsc_timer.dtsi" diff --git a/arch/x86/dts/chromebook_link.dts b/arch/x86/dts/chromebook_link.dts index 26b9f85a5d..115a088a7a 100644 --- a/arch/x86/dts/chromebook_link.dts +++ b/arch/x86/dts/chromebook_link.dts @@ -5,6 +5,7 @@ /include/ "skeleton.dtsi" /include/ "keyboard.dtsi" /include/ "serial.dtsi" +/include/ "reset.dtsi" /include/ "rtc.dtsi" /include/ "tsc_timer.dtsi" /include/ "coreboot_fb.dtsi" diff --git a/arch/x86/dts/chromebook_samus.dts b/arch/x86/dts/chromebook_samus.dts index 52a9ea6622..9c48c9a3fa 100644 --- a/arch/x86/dts/chromebook_samus.dts +++ b/arch/x86/dts/chromebook_samus.dts @@ -5,6 +5,7 @@ /include/ "skeleton.dtsi" /include/ "keyboard.dtsi" /include/ "serial.dtsi" +/include/ "reset.dtsi" /include/ "rtc.dtsi" /include/ "tsc_timer.dtsi" /include/ "coreboot_fb.dtsi" diff --git a/arch/x86/dts/chromebox_panther.dts b/arch/x86/dts/chromebox_panther.dts index b25c9194f3..a72a85ef9c 100644 --- a/arch/x86/dts/chromebox_panther.dts +++ b/arch/x86/dts/chromebox_panther.dts @@ -2,6 +2,7 @@ /include/ "skeleton.dtsi" /include/ "serial.dtsi" +/include/ "reset.dtsi" /include/ "rtc.dtsi" /include/ "tsc_timer.dtsi" /include/ "coreboot_fb.dtsi" diff --git a/arch/x86/dts/conga-qeval20-qa3-e3845.dts b/arch/x86/dts/conga-qeval20-qa3-e3845.dts index c3d15143cf..5884dbc277 100644 --- a/arch/x86/dts/conga-qeval20-qa3-e3845.dts +++ b/arch/x86/dts/conga-qeval20-qa3-e3845.dts @@ -12,6 +12,7 @@ /include/ "skeleton.dtsi" /include/ "serial.dtsi" +/include/ "reset.dtsi" /include/ "rtc.dtsi" /include/ "tsc_timer.dtsi" diff --git a/arch/x86/dts/cougarcanyon2.dts b/arch/x86/dts/cougarcanyon2.dts index c1cda73d96..9801790083 100644 --- a/arch/x86/dts/cougarcanyon2.dts +++ b/arch/x86/dts/cougarcanyon2.dts @@ -10,6 +10,7 @@ /include/ "skeleton.dtsi" /include/ "serial.dtsi" /include/ "keyboard.dtsi" +/include/ "reset.dtsi" /include/ "rtc.dtsi" /include/ "tsc_timer.dtsi" diff --git a/arch/x86/dts/crownbay.dts b/arch/x86/dts/crownbay.dts index d8faa9d504..2ffcc5f27e 100644 --- a/arch/x86/dts/crownbay.dts +++ b/arch/x86/dts/crownbay.dts @@ -10,6 +10,7 @@ /include/ "skeleton.dtsi" /include/ "serial.dtsi" /include/ "keyboard.dtsi" +/include/ "reset.dtsi" /include/ "rtc.dtsi" /include/ "tsc_timer.dtsi" diff --git a/arch/x86/dts/dfi-bt700.dtsi b/arch/x86/dts/dfi-bt700.dtsi index cb96fdf7e7..51d33e772f 100644 --- a/arch/x86/dts/dfi-bt700.dtsi +++ b/arch/x86/dts/dfi-bt700.dtsi @@ -9,6 +9,7 @@ #include #include "skeleton.dtsi" +#include "reset.dtsi" #include "rtc.dtsi" #include "tsc_timer.dtsi" diff --git a/arch/x86/dts/edison.dts b/arch/x86/dts/edison.dts index 9033532294..5c80f5c7fa 100644 --- a/arch/x86/dts/edison.dts +++ b/arch/x86/dts/edison.dts @@ -85,4 +85,9 @@ compatible = "intel,scu-ipc"; reg = <0xff009000 0x1000>; }; + + reset { + compatible = "intel,reset-tangier"; + u-boot,dm-pre-reloc; + }; }; diff --git a/arch/x86/dts/efi-x86_app.dts b/arch/x86/dts/efi-x86_app.dts index e70e351618..20150f6ede 100644 --- a/arch/x86/dts/efi-x86_app.dts +++ b/arch/x86/dts/efi-x86_app.dts @@ -23,4 +23,9 @@ serial: serial { compatible = "efi,uart"; }; + + reset { + compatible = "efi,reset"; + u-boot,dm-pre-reloc; + }; }; diff --git a/arch/x86/dts/efi-x86_payload.dts b/arch/x86/dts/efi-x86_payload.dts index 148b5871aa..19f253064b 100644 --- a/arch/x86/dts/efi-x86_payload.dts +++ b/arch/x86/dts/efi-x86_payload.dts @@ -10,6 +10,7 @@ /include/ "skeleton.dtsi" /include/ "serial.dtsi" /include/ "keyboard.dtsi" +/include/ "reset.dtsi" /include/ "rtc.dtsi" /include/ "tsc_timer.dtsi" diff --git a/arch/x86/dts/galileo.dts b/arch/x86/dts/galileo.dts index 3454abdd33..3a5d168268 100644 --- a/arch/x86/dts/galileo.dts +++ b/arch/x86/dts/galileo.dts @@ -9,6 +9,7 @@ #include /include/ "skeleton.dtsi" +/include/ "reset.dtsi" /include/ "rtc.dtsi" /include/ "tsc_timer.dtsi" diff --git a/arch/x86/dts/minnowmax.dts b/arch/x86/dts/minnowmax.dts index 42ba0c7714..02ab4c160a 100644 --- a/arch/x86/dts/minnowmax.dts +++ b/arch/x86/dts/minnowmax.dts @@ -11,6 +11,7 @@ /include/ "skeleton.dtsi" /include/ "serial.dtsi" +/include/ "reset.dtsi" /include/ "rtc.dtsi" /include/ "tsc_timer.dtsi" /include/ "coreboot_fb.dtsi" diff --git a/arch/x86/dts/qemu-x86_i440fx.dts b/arch/x86/dts/qemu-x86_i440fx.dts index 6565429867..2e5210d4ee 100644 --- a/arch/x86/dts/qemu-x86_i440fx.dts +++ b/arch/x86/dts/qemu-x86_i440fx.dts @@ -10,6 +10,7 @@ /include/ "skeleton.dtsi" /include/ "serial.dtsi" /include/ "keyboard.dtsi" +/include/ "reset.dtsi" /include/ "rtc.dtsi" /include/ "tsc_timer.dtsi" diff --git a/arch/x86/dts/qemu-x86_q35.dts b/arch/x86/dts/qemu-x86_q35.dts index f1c4cb9c03..e8f55b19a2 100644 --- a/arch/x86/dts/qemu-x86_q35.dts +++ b/arch/x86/dts/qemu-x86_q35.dts @@ -20,6 +20,7 @@ /include/ "skeleton.dtsi" /include/ "serial.dtsi" /include/ "keyboard.dtsi" +/include/ "reset.dtsi" /include/ "rtc.dtsi" /include/ "tsc_timer.dtsi" diff --git a/arch/x86/dts/reset.dtsi b/arch/x86/dts/reset.dtsi new file mode 100644 index 0000000000..f979d83757 --- /dev/null +++ b/arch/x86/dts/reset.dtsi @@ -0,0 +1,6 @@ +/ { + reset { + compatible = "x86,reset"; + u-boot,dm-pre-reloc; + }; +}; diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index dd957d2c1b..f1d9977bcb 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -43,11 +43,6 @@ enum { FULL_RST = 1 << 3, /* full power cycle */ }; -/** - * x86_full_reset() - reset everything: perform a full power cycle - */ -void x86_full_reset(void); - static inline __attribute__((always_inline)) void cpu_hlt(void) { asm("hlt"); diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h index 2340ef8332..670fcdc009 100644 --- a/arch/x86/include/asm/u-boot-x86.h +++ b/arch/x86/include/asm/u-boot-x86.h @@ -40,7 +40,6 @@ int x86_cleanup_before_linux(void); void x86_enable_caches(void); void x86_disable_caches(void); int x86_init_cache(void); -void reset_cpu(ulong addr); ulong board_get_usable_ram_top(ulong total_size); int default_print_cpuinfo(void); diff --git a/configs/chromebook_link64_defconfig b/configs/chromebook_link64_defconfig index 59b6bd0dd1..9af2c4de8d 100644 --- a/configs/chromebook_link64_defconfig +++ b/configs/chromebook_link64_defconfig @@ -4,6 +4,7 @@ CONFIG_SPL_LIBCOMMON_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y CONFIG_SYS_MALLOC_F_LEN=0x2000 CONFIG_SPL_SERIAL_SUPPORT=y +CONFIG_SPL_DRIVERS_MISC_SUPPORT=y CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_DEBUG_UART_BASE=0x3f8 CONFIG_DEBUG_UART_CLOCK=1843200 From a0609a8d19d4a9a86572fffb7cb8a3661fffbcf7 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 18 Jul 2018 21:42:15 -0700 Subject: [PATCH 08/10] x86: acpi: Move APIs unrelated to ACPI tables generation to a separate library acpi_find_fadt(), acpi_find_wakeup_vector() and enter_acpi_mode() are something unrelated to ACPI tables generation. Move these to a separate library. This also fixes several style issues reported by checkpatch in the original codes. Signed-off-by: Bin Meng Reviewed-by: Simon Glass Tested-by: Andy Shevchenko --- arch/x86/cpu/cpu.c | 1 + arch/x86/include/asm/acpi.h | 41 ++++++++++++ arch/x86/include/asm/acpi_table.h | 28 -------- arch/x86/lib/Makefile | 1 + arch/x86/lib/acpi.c | 108 ++++++++++++++++++++++++++++++ arch/x86/lib/acpi_s3.c | 1 + arch/x86/lib/acpi_table.c | 101 +--------------------------- 7 files changed, 153 insertions(+), 128 deletions(-) create mode 100644 arch/x86/include/asm/acpi.h create mode 100644 arch/x86/lib/acpi.c diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c index 37615d055a..d08b7d9b1e 100644 --- a/arch/x86/cpu/cpu.c +++ b/arch/x86/cpu/cpu.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h new file mode 100644 index 0000000000..4475d046e8 --- /dev/null +++ b/arch/x86/include/asm/acpi.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2018, Bin Meng + */ + +#ifndef __ASM_ACPI_H__ +#define __ASM_ACPI_H__ + +struct acpi_fadt; + +/** + * acpi_find_fadt() - find ACPI FADT table in the system memory + * + * This routine parses the ACPI table to locate the ACPI FADT table. + * + * @return: a pointer to the ACPI FADT table in the system memory + */ +struct acpi_fadt *acpi_find_fadt(void); + +/** + * acpi_find_wakeup_vector() - find OS installed wake up vector address + * + * This routine parses the ACPI table to locate the wake up vector installed + * by the OS previously. + * + * @fadt: a pointer to the ACPI FADT table in the system memory + * @return: wake up vector address installed by the OS + */ +void *acpi_find_wakeup_vector(struct acpi_fadt *fadt); + +/** + * enter_acpi_mode() - enter into ACPI mode + * + * This programs the ACPI-defined PM1_CNT register to enable SCI interrupt + * so that the whole system swiches to ACPI mode. + * + * @pm1_cnt: PM1_CNT register I/O address + */ +void enter_acpi_mode(int pm1_cnt); + +#endif /* __ASM_ACPI_H__ */ diff --git a/arch/x86/include/asm/acpi_table.h b/arch/x86/include/asm/acpi_table.h index 239bcdc576..dd516df97f 100644 --- a/arch/x86/include/asm/acpi_table.h +++ b/arch/x86/include/asm/acpi_table.h @@ -317,15 +317,6 @@ int acpi_create_mcfg_mmconfig(struct acpi_mcfg_mmconfig *mmconfig, u32 base, u16 seg_nr, u8 start, u8 end); u32 acpi_fill_mcfg(u32 current); void acpi_create_gnvs(struct acpi_global_nvs *gnvs); -/** - * enter_acpi_mode() - enter into ACPI mode - * - * This programs the ACPI-defined PM1_CNT register to enable SCI interrupt - * so that the whole system swiches to ACPI mode. - * - * @pm1_cnt: PM1_CNT register I/O address - */ -void enter_acpi_mode(int pm1_cnt); ulong write_acpi_tables(ulong start); /** @@ -336,22 +327,3 @@ ulong write_acpi_tables(ulong start); * @return: ACPI RSDP table address */ ulong acpi_get_rsdp_addr(void); - -/** - * acpi_find_fadt() - find ACPI FADT table in the sytem memory - * - * This routine parses the ACPI table to locate the ACPI FADT table. - * - * @return: a pointer to the ACPI FADT table in the system memory - */ -struct acpi_fadt *acpi_find_fadt(void); - -/** - * acpi_find_wakeup_vector() - find OS installed wake up vector address - * - * This routine parses the ACPI table to locate the wake up vector installed - * by the OS previously. - * - * @return: wake up vector address installed by the OS - */ -void *acpi_find_wakeup_vector(struct acpi_fadt *); diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index ba07ac728f..1e8efcc44f 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_INTEL_MID) += scu.o obj-y += sections.o obj-y += sfi.o obj-y += string.o +obj-y += acpi.o obj-$(CONFIG_HAVE_ACPI_RESUME) += acpi_s3.o ifndef CONFIG_QEMU obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi_table.o diff --git a/arch/x86/lib/acpi.c b/arch/x86/lib/acpi.c new file mode 100644 index 0000000000..cba9c24dd4 --- /dev/null +++ b/arch/x86/lib/acpi.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018, Bin Meng + */ + +#include +#include +#include +#include + +static struct acpi_rsdp *acpi_valid_rsdp(struct acpi_rsdp *rsdp) +{ + if (strncmp((char *)rsdp, RSDP_SIG, sizeof(RSDP_SIG) - 1) != 0) + return NULL; + + debug("Looking on %p for valid checksum\n", rsdp); + + if (table_compute_checksum((void *)rsdp, 20) != 0) + return NULL; + debug("acpi rsdp checksum 1 passed\n"); + + if ((rsdp->revision > 1) && + (table_compute_checksum((void *)rsdp, rsdp->length) != 0)) + return NULL; + debug("acpi rsdp checksum 2 passed\n"); + + return rsdp; +} + +struct acpi_fadt *acpi_find_fadt(void) +{ + char *p, *end; + struct acpi_rsdp *rsdp = NULL; + struct acpi_rsdt *rsdt; + struct acpi_fadt *fadt = NULL; + int i; + + /* Find RSDP */ + for (p = (char *)ROM_TABLE_ADDR; p < (char *)ROM_TABLE_END; p += 16) { + rsdp = acpi_valid_rsdp((struct acpi_rsdp *)p); + if (rsdp) + break; + } + + if (!rsdp) + return NULL; + + debug("RSDP found at %p\n", rsdp); + rsdt = (struct acpi_rsdt *)(uintptr_t)rsdp->rsdt_address; + + end = (char *)rsdt + rsdt->header.length; + debug("RSDT found at %p ends at %p\n", rsdt, end); + + for (i = 0; ((char *)&rsdt->entry[i]) < end; i++) { + fadt = (struct acpi_fadt *)(uintptr_t)rsdt->entry[i]; + if (strncmp((char *)fadt, "FACP", 4) == 0) + break; + fadt = NULL; + } + + if (!fadt) + return NULL; + + debug("FADT found at %p\n", fadt); + return fadt; +} + +void *acpi_find_wakeup_vector(struct acpi_fadt *fadt) +{ + struct acpi_facs *facs; + void *wake_vec; + + debug("Trying to find the wakeup vector...\n"); + + facs = (struct acpi_facs *)(uintptr_t)fadt->firmware_ctrl; + + if (!facs) { + debug("No FACS found, wake up from S3 not possible.\n"); + return NULL; + } + + debug("FACS found at %p\n", facs); + wake_vec = (void *)(uintptr_t)facs->firmware_waking_vector; + debug("OS waking vector is %p\n", wake_vec); + + return wake_vec; +} + +void enter_acpi_mode(int pm1_cnt) +{ + u16 val = inw(pm1_cnt); + + /* + * PM1_CNT register bit0 selects the power management event to be + * either an SCI or SMI interrupt. When this bit is set, then power + * management events will generate an SCI interrupt. When this bit + * is reset power management events will generate an SMI interrupt. + * + * Per ACPI spec, it is the responsibility of the hardware to set + * or reset this bit. OSPM always preserves this bit position. + * + * U-Boot does not support SMI. And we don't have plan to support + * anything running in SMM within U-Boot. To create a legacy-free + * system, and expose ourselves to OSPM as working under ACPI mode + * already, turn this bit on. + */ + outw(val | PM1_CNT_SCI_EN, pm1_cnt); +} diff --git a/arch/x86/lib/acpi_s3.c b/arch/x86/lib/acpi_s3.c index 514b92ffbd..03917188a9 100644 --- a/arch/x86/lib/acpi_s3.c +++ b/arch/x86/lib/acpi_s3.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c index 7c4321b5ae..e26c54d187 100644 --- a/arch/x86/lib/acpi_table.c +++ b/arch/x86/lib/acpi_table.c @@ -12,8 +12,8 @@ #include #include #include +#include #include -#include #include #include #include @@ -337,27 +337,6 @@ static void acpi_create_mcfg(struct acpi_mcfg *mcfg) header->checksum = table_compute_checksum((void *)mcfg, header->length); } -void enter_acpi_mode(int pm1_cnt) -{ - u16 val = inw(pm1_cnt); - - /* - * PM1_CNT register bit0 selects the power management event to be - * either an SCI or SMI interrupt. When this bit is set, then power - * management events will generate an SCI interrupt. When this bit - * is reset power management events will generate an SMI interrupt. - * - * Per ACPI spec, it is the responsibility of the hardware to set - * or reset this bit. OSPM always preserves this bit position. - * - * U-Boot does not support SMI. And we don't have plan to support - * anything running in SMM within U-Boot. To create a legacy-free - * system, and expose ourselves to OSPM as working under ACPI mode - * already, turn this bit on. - */ - outw(val | PM1_CNT_SCI_EN, pm1_cnt); -} - /* * QEMU's version of write_acpi_tables is defined in drivers/misc/qfw.c */ @@ -482,81 +461,3 @@ ulong acpi_get_rsdp_addr(void) { return acpi_rsdp_addr; } - -static struct acpi_rsdp *acpi_valid_rsdp(struct acpi_rsdp *rsdp) -{ - if (strncmp((char *)rsdp, RSDP_SIG, sizeof(RSDP_SIG) - 1) != 0) - return NULL; - - debug("Looking on %p for valid checksum\n", rsdp); - - if (table_compute_checksum((void *)rsdp, 20) != 0) - return NULL; - debug("acpi rsdp checksum 1 passed\n"); - - if ((rsdp->revision > 1) && - (table_compute_checksum((void *)rsdp, rsdp->length) != 0)) - return NULL; - debug("acpi rsdp checksum 2 passed\n"); - - return rsdp; -} - -struct acpi_fadt *acpi_find_fadt(void) -{ - char *p, *end; - struct acpi_rsdp *rsdp = NULL; - struct acpi_rsdt *rsdt; - struct acpi_fadt *fadt = NULL; - int i; - - /* Find RSDP */ - for (p = (char *)ROM_TABLE_ADDR; p < (char *)ROM_TABLE_END; p += 16) { - rsdp = acpi_valid_rsdp((struct acpi_rsdp *)p); - if (rsdp) - break; - } - - if (rsdp == NULL) - return NULL; - - debug("RSDP found at %p\n", rsdp); - rsdt = (struct acpi_rsdt *)rsdp->rsdt_address; - - end = (char *)rsdt + rsdt->header.length; - debug("RSDT found at %p ends at %p\n", rsdt, end); - - for (i = 0; ((char *)&rsdt->entry[i]) < end; i++) { - fadt = (struct acpi_fadt *)rsdt->entry[i]; - if (strncmp((char *)fadt, "FACP", 4) == 0) - break; - fadt = NULL; - } - - if (fadt == NULL) - return NULL; - - debug("FADT found at %p\n", fadt); - return fadt; -} - -void *acpi_find_wakeup_vector(struct acpi_fadt *fadt) -{ - struct acpi_facs *facs; - void *wake_vec; - - debug("Trying to find the wakeup vector...\n"); - - facs = (struct acpi_facs *)fadt->firmware_ctrl; - - if (facs == NULL) { - debug("No FACS found, wake up from S3 not possible.\n"); - return NULL; - } - - debug("FACS found at %p\n", facs); - wake_vec = (void *)facs->firmware_waking_vector; - debug("OS waking vector is %p\n", wake_vec); - - return wake_vec; -} From 474a62bc74fe923cd6f43e13ca82b1ce2f40e76f Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 18 Jul 2018 21:42:16 -0700 Subject: [PATCH 09/10] x86: acpi: Don't touch ACPI hardware in write_acpi_tables() write_acpi_tables() currently touches ACPI hardware to switch to ACPI mode at the end. Move such operation out of this function, so that it only does what the function name tells us. Signed-off-by: Bin Meng Reviewed-by: Simon Glass Tested-by: Andy Shevchenko --- arch/x86/cpu/cpu.c | 21 ++++++++++++++++++--- arch/x86/lib/acpi_table.c | 11 ----------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c index d08b7d9b1e..290ee084e5 100644 --- a/arch/x86/cpu/cpu.c +++ b/arch/x86/cpu/cpu.c @@ -179,17 +179,32 @@ __weak void board_final_cleanup(void) int last_stage_init(void) { + struct acpi_fadt __maybe_unused *fadt; + board_final_cleanup(); -#if CONFIG_HAVE_ACPI_RESUME - struct acpi_fadt *fadt = acpi_find_fadt(); +#ifdef CONFIG_HAVE_ACPI_RESUME + fadt = acpi_find_fadt(); - if (fadt != NULL && gd->arch.prev_sleep_state == ACPI_S3) + if (fadt && gd->arch.prev_sleep_state == ACPI_S3) acpi_resume(fadt); #endif write_tables(); +#ifdef CONFIG_GENERATE_ACPI_TABLE + fadt = acpi_find_fadt(); + + /* Don't touch ACPI hardware on HW reduced platforms */ + if (fadt && !(fadt->flags & ACPI_FADT_HW_REDUCED_ACPI)) { + /* + * Other than waiting for OSPM to request us to switch to ACPI + * mode, do it by ourselves, since SMI will not be triggered. + */ + enter_acpi_mode(fadt->pm1a_cnt_blk); + } +#endif + return 0; } #endif diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c index e26c54d187..e48c9b9574 100644 --- a/arch/x86/lib/acpi_table.c +++ b/arch/x86/lib/acpi_table.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -444,16 +443,6 @@ ulong write_acpi_tables(ulong start) acpi_rsdp_addr = (unsigned long)rsdp; debug("ACPI: done\n"); - /* Don't touch ACPI hardware on HW reduced platforms */ - if (fadt->flags & ACPI_FADT_HW_REDUCED_ACPI) - return current; - - /* - * Other than waiting for OSPM to request us to switch to ACPI mode, - * do it by ourselves, since SMI will not be triggered. - */ - enter_acpi_mode(fadt->pm1a_cnt_blk); - return current; } From 05855fd31a3f7483534aabe69a7030ff38978510 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 18 Jul 2018 21:42:17 -0700 Subject: [PATCH 10/10] x86: acpi: Prevent acpi_table.h from being included more than once The wrapper #ifndef is currently missing in acpi_table.h. Add it to prevent it from being included multiple times. Signed-off-by: Bin Meng Reviewed-by: Simon Glass --- arch/x86/include/asm/acpi_table.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/x86/include/asm/acpi_table.h b/arch/x86/include/asm/acpi_table.h index dd516df97f..95fae036f6 100644 --- a/arch/x86/include/asm/acpi_table.h +++ b/arch/x86/include/asm/acpi_table.h @@ -6,6 +6,9 @@ * Copyright (C) 2016, Bin Meng */ +#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 */ @@ -327,3 +330,5 @@ ulong write_acpi_tables(ulong start); * @return: ACPI RSDP table address */ ulong acpi_get_rsdp_addr(void); + +#endif /* __ASM_ACPI_TABLE_H__ */