[U-Boot] [PATCH v2 1/4] x86: Implement reset_cpu() correctly for modern CPUs
Bin Meng
bmeng.cn at gmail.com
Wed Apr 29 05:55:41 CEST 2015
On Wed, Apr 29, 2015 at 10:11 AM, 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>
> ---
>
> Changes in v2:
> - Update reset comments to indicate the datasheet section
> - Correct full reset code
>
> arch/x86/cpu/cpu.c | 22 +++++++++-------------
> arch/x86/include/asm/processor.h | 19 +++++++++++++++++++
> 2 files changed, 28 insertions(+), 13 deletions(-)
>
> diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
> index c9614f1..02e66d8 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 | SYS_RST | RST_CPU, PORT_RESET);
> }
>
> int dcache_status(void)
> diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
> index 3e26202..3575d34 100644
> --- a/arch/x86/include/asm/processor.h
> +++ b/arch/x86/include/asm/processor.h
> @@ -25,8 +25,27 @@
>
> #ifndef __ASSEMBLY__
>
> +/*
> + * This register is documented in (for example) the Intel Atom Processor E3800
> + * Product Family Datasheet in "PCU - Power Management Controller (PMC)".
> + *
> + * RST_CNT: Reset Control Register (RST_CNT) Offset cf9.
> + *
> + * The naming follows Intel's naming.
> + */
> #define PORT_RESET 0xcf9
>
> +enum {
> + SYS_RST = 1 << 1, /* 0 for soft reset, 1 for hard reset */
> + RST_CPU = 1 << 2, /* initiate reset */
> + 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");
> --
Reviewed-by: Bin Meng <bmeng.cn at gmail.com>
More information about the U-Boot
mailing list