[U-Boot] [PATCH 1/4] x86: Implement reset_cpu() correctly for modern CPUs
Simon Glass
sjg at chromium.org
Wed Apr 29 04:08:27 CEST 2015
Hi Bin,
On 26 April 2015 at 22:56, Bin Meng <bmeng.cn at gmail.com> wrote:
> 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?
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
More information about the U-Boot
mailing list