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> _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot