[U-Boot] [PATCH 1/4] x86: Implement reset_cpu() correctly for modern CPUs

Bin Meng bmeng.cn at gmail.com
Mon Apr 27 06:56:35 CEST 2015


Hi Simon,

On Sat, Apr 25, 2015 at 11:04 PM, Simon Glass <sjg at chromium.org> wrote:
> The existing code is pretty ancient and is unreliable on modern hardware.
> Generally it will hang.
>
> We can use port 0xcf9 to initiate reset on more modern hardware (say in the
> last 10 years). Update the reset_cpu() function to do this, and add a new
> 'full reset' function to perform a full power cycle.
>
> Signed-off-by: Simon Glass <sjg at chromium.org>
> ---
>
>  arch/x86/cpu/cpu.c               | 22 +++++++++-------------
>  arch/x86/include/asm/processor.h | 11 +++++++++++
>  2 files changed, 20 insertions(+), 13 deletions(-)
>
> diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
> index c9614f1..13b3baa 100644
> --- a/arch/x86/cpu/cpu.c
> +++ b/arch/x86/cpu/cpu.c
> @@ -380,21 +380,17 @@ void  flush_cache(unsigned long dummy1, unsigned long dummy2)
>         asm("wbinvd\n");
>  }
>
> -void __attribute__ ((regparm(0))) generate_gpf(void);
> -
> -/* segment 0x70 is an arbitrary segment which does not exist */
> -asm(".globl generate_gpf\n"
> -       ".hidden generate_gpf\n"
> -       ".type generate_gpf, @function\n"
> -       "generate_gpf:\n"
> -       "ljmp   $0x70, $0x47114711\n");
> -
>  __weak void reset_cpu(ulong addr)
>  {
> -       printf("Resetting using x86 Triple Fault\n");
> -       set_vector(13, generate_gpf);   /* general protection fault handler */
> -       set_vector(8, generate_gpf);    /* double fault handler */
> -       generate_gpf();                 /* start the show */
> +       /* Do a hard reset through the chipset's reset control register */
> +       outb(SYS_RST | RST_CPU, PORT_RESET);
> +       for (;;)
> +               cpu_hlt();
> +}
> +
> +void x86_full_reset(void)
> +{
> +       outb(FULL_RST, PORT_RESET);
>  }
>
>  int dcache_status(void)
> diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
> index 3e26202..a24028d 100644
> --- a/arch/x86/include/asm/processor.h
> +++ b/arch/x86/include/asm/processor.h
> @@ -27,6 +27,17 @@
>
>  #define PORT_RESET             0xcf9
>
> +enum {
> +       SYS_RST         = 1 << 1,       /* clear for soft reset, set for hard */

The comment looks confusing. What does 'clear for soft reset' mean?

> +       RST_CPU         = 1 << 2,       /* initiate reset */

CPU_RST? to follow the same convention as SYS_RST and FULL_RST?

> +       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");
> --

Regards,
Bin


More information about the U-Boot mailing list