Hi Bin, On 26 April 2015 at 22:56, Bin Meng <bmeng...@gmail.com> wrote: > Hi Simon, > > On Sat, Apr 25, 2015 at 11:04 PM, 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> >> --- >> >> 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?
It should do, but I want to follow Intel's register naming. I'll add a bit more detail of where this came from. > >> + 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, Simon _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot