On 28 April 2015 at 21:55, Bin Meng <bmeng...@gmail.com> wrote: > On Wed, Apr 29, 2015 at 10:11 AM, Simon Glass <s...@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 <s...@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...@gmail.com>
Applied to u-boot-x86. _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot