[U-Boot,11/22] x86: acpi: Resume OS if resume vector is found

Message ID 1489674408-17498-12-git-send-email-bmeng.cn@gmail.com
State Accepted
Commit 3a34cae01160d207d50db267585b963cf0a0018d
Delegated to: Bin Meng
Headers show

Commit Message

Bin Meng March 16, 2017, 2:26 p.m.
In an S3 resume path, U-Boot does everything like a cold boot except
in the last_stage_init() it jumps to the OS resume vector.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
---

 arch/x86/cpu/cpu.c             |  8 ++++++++
 arch/x86/include/asm/acpi_s3.h | 10 ++++++++++
 arch/x86/lib/Makefile          |  1 +
 arch/x86/lib/acpi_s3.c         | 26 ++++++++++++++++++++++++++
 4 files changed, 45 insertions(+)
 create mode 100644 arch/x86/lib/acpi_s3.c

Comments

Simon Glass March 21, 2017, 8:06 p.m. | #1
Hi Bin,

On 16 March 2017 at 08:26, Bin Meng <bmeng.cn@gmail.com> wrote:
> In an S3 resume path, U-Boot does everything like a cold boot except
> in the last_stage_init() it jumps to the OS resume vector.
>
> Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
>  arch/x86/cpu/cpu.c             |  8 ++++++++
>  arch/x86/include/asm/acpi_s3.h | 10 ++++++++++
>  arch/x86/lib/Makefile          |  1 +
>  arch/x86/lib/acpi_s3.c         | 26 ++++++++++++++++++++++++++
>  4 files changed, 45 insertions(+)
>  create mode 100644 arch/x86/lib/acpi_s3.c

Reviewed-by: Simon Glass <sjg@chromium.org>

>
> diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
> index 9dde54c..afc8645 100644
> --- a/arch/x86/cpu/cpu.c
> +++ b/arch/x86/cpu/cpu.c
> @@ -26,6 +26,7 @@
>  #include <malloc.h>
>  #include <syscon.h>
>  #include <asm/acpi_s3.h>
> +#include <asm/acpi_table.h>
>  #include <asm/control_regs.h>
>  #include <asm/coreboot_tables.h>
>  #include <asm/cpu.h>
> @@ -204,6 +205,13 @@ __weak void board_final_cleanup(void)
>
>  int last_stage_init(void)
>  {
> +#if CONFIG_HAVE_ACPI_RESUME
> +       void *wake_vector = acpi_find_wakeup_vector();
> +
> +       if (wake_vector != NULL && gd->arch.prev_sleep_state == ACPI_S3)
> +               acpi_resume(wake_vector);
> +#endif
> +
>         write_tables();
>
>         board_final_cleanup();
> diff --git a/arch/x86/include/asm/acpi_s3.h b/arch/x86/include/asm/acpi_s3.h
> index f9d4739..5892a8b 100644
> --- a/arch/x86/include/asm/acpi_s3.h
> +++ b/arch/x86/include/asm/acpi_s3.h
> @@ -100,6 +100,16 @@ enum acpi_sleep_state chipset_prev_sleep_state(void);
>   */
>  void chipset_clear_sleep_state(void);
>
> +/**
> + * acpi_resume() - Do ACPI S3 resume
> + *
> + * This calls U-Boot wake up assembly stub and jumps to OS's wake up vector.
> + *
> + * @wake_vec:  OS wake up vector
> + * @return:    Never returns
> + */
> +void acpi_resume(void *wake_vec);
> +
>  #endif /* __ASSEMBLY__ */
>
>  #endif /* __ASM_ACPI_S3_H__ */
> diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
> index 1c2c085..c61f931 100644
> --- a/arch/x86/lib/Makefile
> +++ b/arch/x86/lib/Makefile
> @@ -35,6 +35,7 @@ obj-$(CONFIG_X86_RAMTEST) += ramtest.o
>  obj-y  += sections.o
>  obj-y += sfi.o
>  obj-y  += string.o
> +obj-$(CONFIG_HAVE_ACPI_RESUME) += acpi_s3.o
>  ifndef CONFIG_QEMU
>  obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi_table.o
>  endif
> diff --git a/arch/x86/lib/acpi_s3.c b/arch/x86/lib/acpi_s3.c
> new file mode 100644
> index 0000000..f679c06
> --- /dev/null
> +++ b/arch/x86/lib/acpi_s3.c
> @@ -0,0 +1,26 @@
> +/*
> + * Copyright (C) 2017, Bin Meng <bmeng.cn@gmail.com>
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <asm/acpi_s3.h>
> +#include <asm/post.h>
> +
> +static void asmlinkage (*acpi_do_wakeup)(void *vector) = (void *)WAKEUP_BASE;
> +
> +static void acpi_jump_to_wakeup(void *vector)
> +{
> +       /* Copy wakeup trampoline in place */
> +       memcpy((void *)WAKEUP_BASE, __wakeup, __wakeup_size);
> +
> +       printf("Jumping to OS waking vector %p\n", vector);

Should this be debug()?

> +       acpi_do_wakeup(vector);
> +}
> +
> +void acpi_resume(void *wake_vec)
> +{
> +       post_code(POST_OS_RESUME);
> +       acpi_jump_to_wakeup(wake_vec);
> +}
> --
> 2.9.2
>

Regards,
Simon
Bin Meng April 12, 2017, 8:14 a.m. | #2
Hi Simon,

On Wed, Mar 22, 2017 at 4:06 AM, Simon Glass <sjg@chromium.org> wrote:
> Hi Bin,
>
> On 16 March 2017 at 08:26, Bin Meng <bmeng.cn@gmail.com> wrote:
>> In an S3 resume path, U-Boot does everything like a cold boot except
>> in the last_stage_init() it jumps to the OS resume vector.
>>
>> Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
>> ---
>>
>>  arch/x86/cpu/cpu.c             |  8 ++++++++
>>  arch/x86/include/asm/acpi_s3.h | 10 ++++++++++
>>  arch/x86/lib/Makefile          |  1 +
>>  arch/x86/lib/acpi_s3.c         | 26 ++++++++++++++++++++++++++
>>  4 files changed, 45 insertions(+)
>>  create mode 100644 arch/x86/lib/acpi_s3.c
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
>>
>> diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
>> index 9dde54c..afc8645 100644
>> --- a/arch/x86/cpu/cpu.c
>> +++ b/arch/x86/cpu/cpu.c
>> @@ -26,6 +26,7 @@
>>  #include <malloc.h>
>>  #include <syscon.h>
>>  #include <asm/acpi_s3.h>
>> +#include <asm/acpi_table.h>
>>  #include <asm/control_regs.h>
>>  #include <asm/coreboot_tables.h>
>>  #include <asm/cpu.h>
>> @@ -204,6 +205,13 @@ __weak void board_final_cleanup(void)
>>
>>  int last_stage_init(void)
>>  {
>> +#if CONFIG_HAVE_ACPI_RESUME
>> +       void *wake_vector = acpi_find_wakeup_vector();
>> +
>> +       if (wake_vector != NULL && gd->arch.prev_sleep_state == ACPI_S3)
>> +               acpi_resume(wake_vector);
>> +#endif
>> +
>>         write_tables();
>>
>>         board_final_cleanup();
>> diff --git a/arch/x86/include/asm/acpi_s3.h b/arch/x86/include/asm/acpi_s3.h
>> index f9d4739..5892a8b 100644
>> --- a/arch/x86/include/asm/acpi_s3.h
>> +++ b/arch/x86/include/asm/acpi_s3.h
>> @@ -100,6 +100,16 @@ enum acpi_sleep_state chipset_prev_sleep_state(void);
>>   */
>>  void chipset_clear_sleep_state(void);
>>
>> +/**
>> + * acpi_resume() - Do ACPI S3 resume
>> + *
>> + * This calls U-Boot wake up assembly stub and jumps to OS's wake up vector.
>> + *
>> + * @wake_vec:  OS wake up vector
>> + * @return:    Never returns
>> + */
>> +void acpi_resume(void *wake_vec);
>> +
>>  #endif /* __ASSEMBLY__ */
>>
>>  #endif /* __ASM_ACPI_S3_H__ */
>> diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
>> index 1c2c085..c61f931 100644
>> --- a/arch/x86/lib/Makefile
>> +++ b/arch/x86/lib/Makefile
>> @@ -35,6 +35,7 @@ obj-$(CONFIG_X86_RAMTEST) += ramtest.o
>>  obj-y  += sections.o
>>  obj-y += sfi.o
>>  obj-y  += string.o
>> +obj-$(CONFIG_HAVE_ACPI_RESUME) += acpi_s3.o
>>  ifndef CONFIG_QEMU
>>  obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi_table.o
>>  endif
>> diff --git a/arch/x86/lib/acpi_s3.c b/arch/x86/lib/acpi_s3.c
>> new file mode 100644
>> index 0000000..f679c06
>> --- /dev/null
>> +++ b/arch/x86/lib/acpi_s3.c
>> @@ -0,0 +1,26 @@
>> +/*
>> + * Copyright (C) 2017, Bin Meng <bmeng.cn@gmail.com>
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> + */
>> +
>> +#include <common.h>
>> +#include <asm/acpi_s3.h>
>> +#include <asm/post.h>
>> +
>> +static void asmlinkage (*acpi_do_wakeup)(void *vector) = (void *)WAKEUP_BASE;
>> +
>> +static void acpi_jump_to_wakeup(void *vector)
>> +{
>> +       /* Copy wakeup trampoline in place */
>> +       memcpy((void *)WAKEUP_BASE, __wakeup, __wakeup_size);
>> +
>> +       printf("Jumping to OS waking vector %p\n", vector);
>
> Should this be debug()?
>

I wanted to explicitly print this to show that we are in S3 and
jumping to OS vector. Actually I was even thinking we should introduce
a log level for U-Boot, just like coreboot/linux.

Regards,
Bin
Simon Glass April 13, 2017, 9:15 p.m. | #3
Hi Bin,

On 12 April 2017 at 02:14, Bin Meng <bmeng.cn@gmail.com> wrote:
>
> Hi Simon,
>
> On Wed, Mar 22, 2017 at 4:06 AM, Simon Glass <sjg@chromium.org> wrote:
> > Hi Bin,
> >
> > On 16 March 2017 at 08:26, Bin Meng <bmeng.cn@gmail.com> wrote:
> >> In an S3 resume path, U-Boot does everything like a cold boot except
> >> in the last_stage_init() it jumps to the OS resume vector.
> >>
> >> Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
> >> ---
> >>
> >>  arch/x86/cpu/cpu.c             |  8 ++++++++
> >>  arch/x86/include/asm/acpi_s3.h | 10 ++++++++++
> >>  arch/x86/lib/Makefile          |  1 +
> >>  arch/x86/lib/acpi_s3.c         | 26 ++++++++++++++++++++++++++
> >>  4 files changed, 45 insertions(+)
> >>  create mode 100644 arch/x86/lib/acpi_s3.c
> >
> > Reviewed-by: Simon Glass <sjg@chromium.org>
> >
> >>
> >> diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
> >> index 9dde54c..afc8645 100644
> >> --- a/arch/x86/cpu/cpu.c
> >> +++ b/arch/x86/cpu/cpu.c
> >> @@ -26,6 +26,7 @@
> >>  #include <malloc.h>
> >>  #include <syscon.h>
> >>  #include <asm/acpi_s3.h>
> >> +#include <asm/acpi_table.h>
> >>  #include <asm/control_regs.h>
> >>  #include <asm/coreboot_tables.h>
> >>  #include <asm/cpu.h>
> >> @@ -204,6 +205,13 @@ __weak void board_final_cleanup(void)
> >>
> >>  int last_stage_init(void)
> >>  {
> >> +#if CONFIG_HAVE_ACPI_RESUME
> >> +       void *wake_vector = acpi_find_wakeup_vector();
> >> +
> >> +       if (wake_vector != NULL && gd->arch.prev_sleep_state == ACPI_S3)
> >> +               acpi_resume(wake_vector);
> >> +#endif
> >> +
> >>         write_tables();
> >>
> >>         board_final_cleanup();
> >> diff --git a/arch/x86/include/asm/acpi_s3.h b/arch/x86/include/asm/acpi_s3.h
> >> index f9d4739..5892a8b 100644
> >> --- a/arch/x86/include/asm/acpi_s3.h
> >> +++ b/arch/x86/include/asm/acpi_s3.h
> >> @@ -100,6 +100,16 @@ enum acpi_sleep_state chipset_prev_sleep_state(void);
> >>   */
> >>  void chipset_clear_sleep_state(void);
> >>
> >> +/**
> >> + * acpi_resume() - Do ACPI S3 resume
> >> + *
> >> + * This calls U-Boot wake up assembly stub and jumps to OS's wake up vector.
> >> + *
> >> + * @wake_vec:  OS wake up vector
> >> + * @return:    Never returns
> >> + */
> >> +void acpi_resume(void *wake_vec);
> >> +
> >>  #endif /* __ASSEMBLY__ */
> >>
> >>  #endif /* __ASM_ACPI_S3_H__ */
> >> diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
> >> index 1c2c085..c61f931 100644
> >> --- a/arch/x86/lib/Makefile
> >> +++ b/arch/x86/lib/Makefile
> >> @@ -35,6 +35,7 @@ obj-$(CONFIG_X86_RAMTEST) += ramtest.o
> >>  obj-y  += sections.o
> >>  obj-y += sfi.o
> >>  obj-y  += string.o
> >> +obj-$(CONFIG_HAVE_ACPI_RESUME) += acpi_s3.o
> >>  ifndef CONFIG_QEMU
> >>  obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi_table.o
> >>  endif
> >> diff --git a/arch/x86/lib/acpi_s3.c b/arch/x86/lib/acpi_s3.c
> >> new file mode 100644
> >> index 0000000..f679c06
> >> --- /dev/null
> >> +++ b/arch/x86/lib/acpi_s3.c
> >> @@ -0,0 +1,26 @@
> >> +/*
> >> + * Copyright (C) 2017, Bin Meng <bmeng.cn@gmail.com>
> >> + *
> >> + * SPDX-License-Identifier:    GPL-2.0+
> >> + */
> >> +
> >> +#include <common.h>
> >> +#include <asm/acpi_s3.h>
> >> +#include <asm/post.h>
> >> +
> >> +static void asmlinkage (*acpi_do_wakeup)(void *vector) = (void *)WAKEUP_BASE;
> >> +
> >> +static void acpi_jump_to_wakeup(void *vector)
> >> +{
> >> +       /* Copy wakeup trampoline in place */
> >> +       memcpy((void *)WAKEUP_BASE, __wakeup, __wakeup_size);
> >> +
> >> +       printf("Jumping to OS waking vector %p\n", vector);
> >
> > Should this be debug()?
> >
>
> I wanted to explicitly print this to show that we are in S3 and
> jumping to OS vector. Actually I was even thinking we should introduce
> a log level for U-Boot, just like coreboot/linux.

OK sounds good.

Since you are thinking about logging, here are the features I'd love to see:

- Log messages have category, log level, filename and line number (but
many people would continue to just use debug())
- Ability to enable at build time on a per-file basis (as now) or globally.
- Separately, be able to enable/disable per file at run-time (assuming
enabled at build time)
- Ability to filter log messages that go to console
- Collection of log messages in a buffer (perhaps a circular membuff
or a plain buffer)
- A command to access the log

Regards,
Simon
Stefan Roese April 17, 2017, 9:37 a.m. | #4
Hi Bin,

On 12.04.2017 10:14, Bin Meng wrote:
> On Wed, Mar 22, 2017 at 4:06 AM, Simon Glass <sjg@chromium.org> wrote:
>> Hi Bin,
>>
>> On 16 March 2017 at 08:26, Bin Meng <bmeng.cn@gmail.com> wrote:
>>> In an S3 resume path, U-Boot does everything like a cold boot except
>>> in the last_stage_init() it jumps to the OS resume vector.
>>>
>>> Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
>>> ---
>>>
>>>  arch/x86/cpu/cpu.c             |  8 ++++++++
>>>  arch/x86/include/asm/acpi_s3.h | 10 ++++++++++
>>>  arch/x86/lib/Makefile          |  1 +
>>>  arch/x86/lib/acpi_s3.c         | 26 ++++++++++++++++++++++++++
>>>  4 files changed, 45 insertions(+)
>>>  create mode 100644 arch/x86/lib/acpi_s3.c
>>
>> Reviewed-by: Simon Glass <sjg@chromium.org>
>>
>>>
>>> diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
>>> index 9dde54c..afc8645 100644
>>> --- a/arch/x86/cpu/cpu.c
>>> +++ b/arch/x86/cpu/cpu.c
>>> @@ -26,6 +26,7 @@
>>>  #include <malloc.h>
>>>  #include <syscon.h>
>>>  #include <asm/acpi_s3.h>
>>> +#include <asm/acpi_table.h>
>>>  #include <asm/control_regs.h>
>>>  #include <asm/coreboot_tables.h>
>>>  #include <asm/cpu.h>
>>> @@ -204,6 +205,13 @@ __weak void board_final_cleanup(void)
>>>
>>>  int last_stage_init(void)
>>>  {
>>> +#if CONFIG_HAVE_ACPI_RESUME
>>> +       void *wake_vector = acpi_find_wakeup_vector();
>>> +
>>> +       if (wake_vector != NULL && gd->arch.prev_sleep_state == ACPI_S3)
>>> +               acpi_resume(wake_vector);
>>> +#endif
>>> +
>>>         write_tables();
>>>
>>>         board_final_cleanup();
>>> diff --git a/arch/x86/include/asm/acpi_s3.h b/arch/x86/include/asm/acpi_s3.h
>>> index f9d4739..5892a8b 100644
>>> --- a/arch/x86/include/asm/acpi_s3.h
>>> +++ b/arch/x86/include/asm/acpi_s3.h
>>> @@ -100,6 +100,16 @@ enum acpi_sleep_state chipset_prev_sleep_state(void);
>>>   */
>>>  void chipset_clear_sleep_state(void);
>>>
>>> +/**
>>> + * acpi_resume() - Do ACPI S3 resume
>>> + *
>>> + * This calls U-Boot wake up assembly stub and jumps to OS's wake up vector.
>>> + *
>>> + * @wake_vec:  OS wake up vector
>>> + * @return:    Never returns
>>> + */
>>> +void acpi_resume(void *wake_vec);
>>> +
>>>  #endif /* __ASSEMBLY__ */
>>>
>>>  #endif /* __ASM_ACPI_S3_H__ */
>>> diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
>>> index 1c2c085..c61f931 100644
>>> --- a/arch/x86/lib/Makefile
>>> +++ b/arch/x86/lib/Makefile
>>> @@ -35,6 +35,7 @@ obj-$(CONFIG_X86_RAMTEST) += ramtest.o
>>>  obj-y  += sections.o
>>>  obj-y += sfi.o
>>>  obj-y  += string.o
>>> +obj-$(CONFIG_HAVE_ACPI_RESUME) += acpi_s3.o
>>>  ifndef CONFIG_QEMU
>>>  obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi_table.o
>>>  endif
>>> diff --git a/arch/x86/lib/acpi_s3.c b/arch/x86/lib/acpi_s3.c
>>> new file mode 100644
>>> index 0000000..f679c06
>>> --- /dev/null
>>> +++ b/arch/x86/lib/acpi_s3.c
>>> @@ -0,0 +1,26 @@
>>> +/*
>>> + * Copyright (C) 2017, Bin Meng <bmeng.cn@gmail.com>
>>> + *
>>> + * SPDX-License-Identifier:    GPL-2.0+
>>> + */
>>> +
>>> +#include <common.h>
>>> +#include <asm/acpi_s3.h>
>>> +#include <asm/post.h>
>>> +
>>> +static void asmlinkage (*acpi_do_wakeup)(void *vector) = (void *)WAKEUP_BASE;
>>> +
>>> +static void acpi_jump_to_wakeup(void *vector)
>>> +{
>>> +       /* Copy wakeup trampoline in place */
>>> +       memcpy((void *)WAKEUP_BASE, __wakeup, __wakeup_size);
>>> +
>>> +       printf("Jumping to OS waking vector %p\n", vector);
>>
>> Should this be debug()?
>>
> 
> I wanted to explicitly print this to show that we are in S3 and
> jumping to OS vector.

I also vote for this explicit print line in this case.

> Actually I was even thinking we should introduce
> a log level for U-Boot, just like coreboot/linux.

Interesting idea. How could the log-level be configured in U-Boot?
Via some env variable?

Thanks,
Stefan
Simon Glass April 24, 2017, 3:38 a.m. | #5
Hi Stefan,

On 17 April 2017 at 03:37, Stefan Roese <sr@denx.de> wrote:
> Hi Bin,
>
> On 12.04.2017 10:14, Bin Meng wrote:
>> On Wed, Mar 22, 2017 at 4:06 AM, Simon Glass <sjg@chromium.org> wrote:
>>> Hi Bin,
>>>
>>> On 16 March 2017 at 08:26, Bin Meng <bmeng.cn@gmail.com> wrote:
>>>> In an S3 resume path, U-Boot does everything like a cold boot except
>>>> in the last_stage_init() it jumps to the OS resume vector.
>>>>
>>>> Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
>>>> ---
>>>>
>>>>  arch/x86/cpu/cpu.c             |  8 ++++++++
>>>>  arch/x86/include/asm/acpi_s3.h | 10 ++++++++++
>>>>  arch/x86/lib/Makefile          |  1 +
>>>>  arch/x86/lib/acpi_s3.c         | 26 ++++++++++++++++++++++++++
>>>>  4 files changed, 45 insertions(+)
>>>>  create mode 100644 arch/x86/lib/acpi_s3.c
>>>
>>> Reviewed-by: Simon Glass <sjg@chromium.org>
>>>
>>>>
>>>> diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
>>>> index 9dde54c..afc8645 100644
>>>> --- a/arch/x86/cpu/cpu.c
>>>> +++ b/arch/x86/cpu/cpu.c
>>>> @@ -26,6 +26,7 @@
>>>>  #include <malloc.h>
>>>>  #include <syscon.h>
>>>>  #include <asm/acpi_s3.h>
>>>> +#include <asm/acpi_table.h>
>>>>  #include <asm/control_regs.h>
>>>>  #include <asm/coreboot_tables.h>
>>>>  #include <asm/cpu.h>
>>>> @@ -204,6 +205,13 @@ __weak void board_final_cleanup(void)
>>>>
>>>>  int last_stage_init(void)
>>>>  {
>>>> +#if CONFIG_HAVE_ACPI_RESUME
>>>> +       void *wake_vector = acpi_find_wakeup_vector();
>>>> +
>>>> +       if (wake_vector != NULL && gd->arch.prev_sleep_state == ACPI_S3)
>>>> +               acpi_resume(wake_vector);
>>>> +#endif
>>>> +
>>>>         write_tables();
>>>>
>>>>         board_final_cleanup();
>>>> diff --git a/arch/x86/include/asm/acpi_s3.h b/arch/x86/include/asm/acpi_s3.h
>>>> index f9d4739..5892a8b 100644
>>>> --- a/arch/x86/include/asm/acpi_s3.h
>>>> +++ b/arch/x86/include/asm/acpi_s3.h
>>>> @@ -100,6 +100,16 @@ enum acpi_sleep_state chipset_prev_sleep_state(void);
>>>>   */
>>>>  void chipset_clear_sleep_state(void);
>>>>
>>>> +/**
>>>> + * acpi_resume() - Do ACPI S3 resume
>>>> + *
>>>> + * This calls U-Boot wake up assembly stub and jumps to OS's wake up vector.
>>>> + *
>>>> + * @wake_vec:  OS wake up vector
>>>> + * @return:    Never returns
>>>> + */
>>>> +void acpi_resume(void *wake_vec);
>>>> +
>>>>  #endif /* __ASSEMBLY__ */
>>>>
>>>>  #endif /* __ASM_ACPI_S3_H__ */
>>>> diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
>>>> index 1c2c085..c61f931 100644
>>>> --- a/arch/x86/lib/Makefile
>>>> +++ b/arch/x86/lib/Makefile
>>>> @@ -35,6 +35,7 @@ obj-$(CONFIG_X86_RAMTEST) += ramtest.o
>>>>  obj-y  += sections.o
>>>>  obj-y += sfi.o
>>>>  obj-y  += string.o
>>>> +obj-$(CONFIG_HAVE_ACPI_RESUME) += acpi_s3.o
>>>>  ifndef CONFIG_QEMU
>>>>  obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi_table.o
>>>>  endif
>>>> diff --git a/arch/x86/lib/acpi_s3.c b/arch/x86/lib/acpi_s3.c
>>>> new file mode 100644
>>>> index 0000000..f679c06
>>>> --- /dev/null
>>>> +++ b/arch/x86/lib/acpi_s3.c
>>>> @@ -0,0 +1,26 @@
>>>> +/*
>>>> + * Copyright (C) 2017, Bin Meng <bmeng.cn@gmail.com>
>>>> + *
>>>> + * SPDX-License-Identifier:    GPL-2.0+
>>>> + */
>>>> +
>>>> +#include <common.h>
>>>> +#include <asm/acpi_s3.h>
>>>> +#include <asm/post.h>
>>>> +
>>>> +static void asmlinkage (*acpi_do_wakeup)(void *vector) = (void *)WAKEUP_BASE;
>>>> +
>>>> +static void acpi_jump_to_wakeup(void *vector)
>>>> +{
>>>> +       /* Copy wakeup trampoline in place */
>>>> +       memcpy((void *)WAKEUP_BASE, __wakeup, __wakeup_size);
>>>> +
>>>> +       printf("Jumping to OS waking vector %p\n", vector);
>>>
>>> Should this be debug()?
>>>
>>
>> I wanted to explicitly print this to show that we are in S3 and
>> jumping to OS vector.
>
> I also vote for this explicit print line in this case.
>
>> Actually I was even thinking we should introduce
>> a log level for U-Boot, just like coreboot/linux.
>
> Interesting idea. How could the log-level be configured in U-Boot?
> Via some env variable?

Yes I suppose so.

Regards,
Simon

Patch

diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
index 9dde54c..afc8645 100644
--- a/arch/x86/cpu/cpu.c
+++ b/arch/x86/cpu/cpu.c
@@ -26,6 +26,7 @@ 
 #include <malloc.h>
 #include <syscon.h>
 #include <asm/acpi_s3.h>
+#include <asm/acpi_table.h>
 #include <asm/control_regs.h>
 #include <asm/coreboot_tables.h>
 #include <asm/cpu.h>
@@ -204,6 +205,13 @@  __weak void board_final_cleanup(void)
 
 int last_stage_init(void)
 {
+#if CONFIG_HAVE_ACPI_RESUME
+	void *wake_vector = acpi_find_wakeup_vector();
+
+	if (wake_vector != NULL && gd->arch.prev_sleep_state == ACPI_S3)
+		acpi_resume(wake_vector);
+#endif
+
 	write_tables();
 
 	board_final_cleanup();
diff --git a/arch/x86/include/asm/acpi_s3.h b/arch/x86/include/asm/acpi_s3.h
index f9d4739..5892a8b 100644
--- a/arch/x86/include/asm/acpi_s3.h
+++ b/arch/x86/include/asm/acpi_s3.h
@@ -100,6 +100,16 @@  enum acpi_sleep_state chipset_prev_sleep_state(void);
  */
 void chipset_clear_sleep_state(void);
 
+/**
+ * acpi_resume() - Do ACPI S3 resume
+ *
+ * This calls U-Boot wake up assembly stub and jumps to OS's wake up vector.
+ *
+ * @wake_vec:	OS wake up vector
+ * @return:	Never returns
+ */
+void acpi_resume(void *wake_vec);
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __ASM_ACPI_S3_H__ */
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 1c2c085..c61f931 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -35,6 +35,7 @@  obj-$(CONFIG_X86_RAMTEST) += ramtest.o
 obj-y	+= sections.o
 obj-y += sfi.o
 obj-y	+= string.o
+obj-$(CONFIG_HAVE_ACPI_RESUME) += acpi_s3.o
 ifndef CONFIG_QEMU
 obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi_table.o
 endif
diff --git a/arch/x86/lib/acpi_s3.c b/arch/x86/lib/acpi_s3.c
new file mode 100644
index 0000000..f679c06
--- /dev/null
+++ b/arch/x86/lib/acpi_s3.c
@@ -0,0 +1,26 @@ 
+/*
+ * Copyright (C) 2017, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/acpi_s3.h>
+#include <asm/post.h>
+
+static void asmlinkage (*acpi_do_wakeup)(void *vector) = (void *)WAKEUP_BASE;
+
+static void acpi_jump_to_wakeup(void *vector)
+{
+	/* Copy wakeup trampoline in place */
+	memcpy((void *)WAKEUP_BASE, __wakeup, __wakeup_size);
+
+	printf("Jumping to OS waking vector %p\n", vector);
+	acpi_do_wakeup(vector);
+}
+
+void acpi_resume(void *wake_vec)
+{
+	post_code(POST_OS_RESUME);
+	acpi_jump_to_wakeup(wake_vec);
+}