diff mbox

[U-Boot,20/39] x86: Emit post codes in startup code

Message ID 1415305231-30180-21-git-send-email-sjg@chromium.org
State Superseded
Delegated to: Simon Glass
Headers show

Commit Message

Simon Glass Nov. 6, 2014, 8:20 p.m. UTC
On x86 it is common to use 'post codes' which are 8-bit hex values emitted
from the code and visible to the user. Traditionally two 7-segment displays
were made available on the motherboard to show the last post code that was
emitted. This allows diagnosis of a boot problem since it is possible to
see where the code got to before it died.

On modern hardware these codes are not normally visible. On Chromebooks
they are displayed by the Embedded Controller (EC), so it is useful to emit
them. We must enable this feature for the EC to see the codes, so add an
option for this.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 arch/x86/cpu/coreboot/coreboot.c     |  3 ++-
 arch/x86/cpu/start.S                 | 25 +++++++++++++++++++++++++
 arch/x86/include/asm/post.h          | 32 ++++++++++++++++++++++++++++++++
 board/google/chromebook_link/Kconfig |  4 ++++
 4 files changed, 63 insertions(+), 1 deletion(-)
 create mode 100644 arch/x86/include/asm/post.h

Comments

Bin Meng Nov. 7, 2014, 1:37 p.m. UTC | #1
Hi Simon,

On Fri, Nov 7, 2014 at 4:20 AM, Simon Glass <sjg@chromium.org> wrote:
> On x86 it is common to use 'post codes' which are 8-bit hex values emitted
> from the code and visible to the user. Traditionally two 7-segment displays
> were made available on the motherboard to show the last post code that was
> emitted. This allows diagnosis of a boot problem since it is possible to
> see where the code got to before it died.
>
> On modern hardware these codes are not normally visible. On Chromebooks
> they are displayed by the Embedded Controller (EC), so it is useful to emit
> them. We must enable this feature for the EC to see the codes, so add an
> option for this.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
>  arch/x86/cpu/coreboot/coreboot.c     |  3 ++-
>  arch/x86/cpu/start.S                 | 25 +++++++++++++++++++++++++
>  arch/x86/include/asm/post.h          | 32 ++++++++++++++++++++++++++++++++
>  board/google/chromebook_link/Kconfig |  4 ++++
>  4 files changed, 63 insertions(+), 1 deletion(-)
>  create mode 100644 arch/x86/include/asm/post.h
>
> diff --git a/arch/x86/cpu/coreboot/coreboot.c b/arch/x86/cpu/coreboot/coreboot.c
> index 257faa1..cc7398f 100644
> --- a/arch/x86/cpu/coreboot/coreboot.c
> +++ b/arch/x86/cpu/coreboot/coreboot.c
> @@ -15,6 +15,7 @@
>  #include <asm/cache.h>
>  #include <asm/cpu.h>
>  #include <asm/io.h>
> +#include <asm/post.h>
>  #include <asm/arch-coreboot/tables.h>
>  #include <asm/arch-coreboot/sysinfo.h>
>  #include <asm/arch/timestamp.h>
> @@ -68,7 +69,7 @@ void show_boot_progress(int val)
>                 gd->arch.tsc_prev = now;
>         }
>  #endif
> -       outb(val, 0x80);
> +       outb(val, POST_PORT);
>  }
>
>  int last_stage_init(void)
> diff --git a/arch/x86/cpu/start.S b/arch/x86/cpu/start.S
> index 7f41475..f62ffeb 100644
> --- a/arch/x86/cpu/start.S
> +++ b/arch/x86/cpu/start.S
> @@ -13,6 +13,7 @@
>  #include <config.h>
>  #include <version.h>
>  #include <asm/global_data.h>
> +#include <asm/post.h>
>  #include <asm/processor.h>
>  #include <asm/processor-flags.h>
>  #include <generated/generic-asm-offsets.h>
> @@ -60,6 +61,28 @@ _start:
>         movw    %ax, %es
>         movw    %ax, %ss
>
> +       /* Enable post codes to EC */
> +#ifdef CONFIG_EARLY_POST_CROS_EC
> +       mov    $0x1b, %ecx
> +       rdmsr
> +       and    $0x100, %eax
> +       test   %eax, %eax
> +       je     2f
> +
> +       mov    $0x8000f8f0, %eax
> +       mov    $0xcf8, %dx
> +       out    %eax, (%dx)
> +       mov    $0xfed1c001, %eax
> +       mov    $0xcfc, %dx
> +       out    %eax, (%dx)
> +       mov    $0xfed1f410, %esp
> +       mov    (%esp), %eax
> +       and    $0xfffffffb, %eax
> +       mov    %eax, (%esp)
> +2:
> +#endif

IMHO the early_board_init() removal should be rolled back, and the
enable post codes is better to put there.

> +       post_code(POST_START)
> +
>         /* Clear the interrupt vectors */
>         lidt    blank_idt_ptr
>
> @@ -91,6 +114,7 @@ car_init_ret:
>
>         /* Align global data to 16-byte boundary */
>         andl    $0xfffffff0, %esp
> +       post_code(POST_START_STACK)
>
>         /* Zero the global data since it won't happen later */
>         xorl    %eax, %eax
> @@ -126,6 +150,7 @@ car_init_ret:
>         call    setup_gdt
>
>         /* Set parameter to board_init_f() to boot flags */
> +       post_code(POST_START_DONE)
>         xorl    %eax, %eax
>
>         /* Enter, U-boot! */
> diff --git a/arch/x86/include/asm/post.h b/arch/x86/include/asm/post.h
> new file mode 100644
> index 0000000..3371185
> --- /dev/null
> +++ b/arch/x86/include/asm/post.h
> @@ -0,0 +1,32 @@
> +/*
> + * Copyright (c) 2014 Google, Inc
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#ifndef _post_h
> +#define _post_h
> +
> +/* port to use for post codes */
> +#define POST_PORT              0x80
> +
> +/* post codes which represent various stages of init */
> +#define POST_START             0x1e
> +#define POST_CAR_START         0x1f
> +
> +#define POST_START_STACK       0x29
> +#define POST_START_DONE                0x2a

Do we follow some specification about post codes values, or are them
just some random numbers?

> +/* Output a post code using al - value must be 0 to 0xff */
> +#ifdef __ASSEMBLY__
> +#define post_code(value) \
> +       movb    $value, %al; \
> +       outb    %al, $POST_PORT
> +#else
> +static inline void post_code(int code)
> +{
> +       outb(code, POST_PORT);
> +}
> +#endif
> +
> +#endif
> diff --git a/board/google/chromebook_link/Kconfig b/board/google/chromebook_link/Kconfig
> index 975d557..9c715ba 100644
> --- a/board/google/chromebook_link/Kconfig
> +++ b/board/google/chromebook_link/Kconfig
> @@ -12,4 +12,8 @@ config SYS_SOC
>  config SYS_CONFIG_NAME
>         default "chromebook_link"
>
> +config EARLY_POST_CROS_EC
> +       bool "Enable early post to Chrome OS EC"
> +       default y
> +
>  endif
> --

Regards,
Bin
Simon Glass Nov. 7, 2014, 2:41 p.m. UTC | #2
Hi Bin,

On 7 November 2014 06:37, Bin Meng <bmeng.cn@gmail.com> wrote:
> Hi Simon,
>
> On Fri, Nov 7, 2014 at 4:20 AM, Simon Glass <sjg@chromium.org> wrote:
>> On x86 it is common to use 'post codes' which are 8-bit hex values emitted
>> from the code and visible to the user. Traditionally two 7-segment displays
>> were made available on the motherboard to show the last post code that was
>> emitted. This allows diagnosis of a boot problem since it is possible to
>> see where the code got to before it died.
>>
>> On modern hardware these codes are not normally visible. On Chromebooks
>> they are displayed by the Embedded Controller (EC), so it is useful to emit
>> them. We must enable this feature for the EC to see the codes, so add an
>> option for this.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>>  arch/x86/cpu/coreboot/coreboot.c     |  3 ++-
>>  arch/x86/cpu/start.S                 | 25 +++++++++++++++++++++++++
>>  arch/x86/include/asm/post.h          | 32 ++++++++++++++++++++++++++++++++
>>  board/google/chromebook_link/Kconfig |  4 ++++
>>  4 files changed, 63 insertions(+), 1 deletion(-)
>>  create mode 100644 arch/x86/include/asm/post.h
>>
>> diff --git a/arch/x86/cpu/coreboot/coreboot.c b/arch/x86/cpu/coreboot/coreboot.c
>> index 257faa1..cc7398f 100644
>> --- a/arch/x86/cpu/coreboot/coreboot.c
>> +++ b/arch/x86/cpu/coreboot/coreboot.c
>> @@ -15,6 +15,7 @@
>>  #include <asm/cache.h>
>>  #include <asm/cpu.h>
>>  #include <asm/io.h>
>> +#include <asm/post.h>
>>  #include <asm/arch-coreboot/tables.h>
>>  #include <asm/arch-coreboot/sysinfo.h>
>>  #include <asm/arch/timestamp.h>
>> @@ -68,7 +69,7 @@ void show_boot_progress(int val)
>>                 gd->arch.tsc_prev = now;
>>         }
>>  #endif
>> -       outb(val, 0x80);
>> +       outb(val, POST_PORT);
>>  }
>>
>>  int last_stage_init(void)
>> diff --git a/arch/x86/cpu/start.S b/arch/x86/cpu/start.S
>> index 7f41475..f62ffeb 100644
>> --- a/arch/x86/cpu/start.S
>> +++ b/arch/x86/cpu/start.S
>> @@ -13,6 +13,7 @@
>>  #include <config.h>
>>  #include <version.h>
>>  #include <asm/global_data.h>
>> +#include <asm/post.h>
>>  #include <asm/processor.h>
>>  #include <asm/processor-flags.h>
>>  #include <generated/generic-asm-offsets.h>
>> @@ -60,6 +61,28 @@ _start:
>>         movw    %ax, %es
>>         movw    %ax, %ss
>>
>> +       /* Enable post codes to EC */
>> +#ifdef CONFIG_EARLY_POST_CROS_EC
>> +       mov    $0x1b, %ecx
>> +       rdmsr
>> +       and    $0x100, %eax
>> +       test   %eax, %eax
>> +       je     2f
>> +
>> +       mov    $0x8000f8f0, %eax
>> +       mov    $0xcf8, %dx
>> +       out    %eax, (%dx)
>> +       mov    $0xfed1c001, %eax
>> +       mov    $0xcfc, %dx
>> +       out    %eax, (%dx)
>> +       mov    $0xfed1f410, %esp
>> +       mov    (%esp), %eax
>> +       and    $0xfffffffb, %eax
>> +       mov    %eax, (%esp)
>> +2:
>> +#endif
>
> IMHO the early_board_init() removal should be rolled back, and the
> enable post codes is better to put there.

Yes I was thinking about that, I'll make that change.

>
>> +       post_code(POST_START)
>> +
>>         /* Clear the interrupt vectors */
>>         lidt    blank_idt_ptr
>>
>> @@ -91,6 +114,7 @@ car_init_ret:
>>
>>         /* Align global data to 16-byte boundary */
>>         andl    $0xfffffff0, %esp
>> +       post_code(POST_START_STACK)
>>
>>         /* Zero the global data since it won't happen later */
>>         xorl    %eax, %eax
>> @@ -126,6 +150,7 @@ car_init_ret:
>>         call    setup_gdt
>>
>>         /* Set parameter to board_init_f() to boot flags */
>> +       post_code(POST_START_DONE)
>>         xorl    %eax, %eax
>>
>>         /* Enter, U-boot! */
>> diff --git a/arch/x86/include/asm/post.h b/arch/x86/include/asm/post.h
>> new file mode 100644
>> index 0000000..3371185
>> --- /dev/null
>> +++ b/arch/x86/include/asm/post.h
>> @@ -0,0 +1,32 @@
>> +/*
>> + * Copyright (c) 2014 Google, Inc
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> + */
>> +
>> +#ifndef _post_h
>> +#define _post_h
>> +
>> +/* port to use for post codes */
>> +#define POST_PORT              0x80
>> +
>> +/* post codes which represent various stages of init */
>> +#define POST_START             0x1e
>> +#define POST_CAR_START         0x1f
>> +
>> +#define POST_START_STACK       0x29
>> +#define POST_START_DONE                0x2a
>
> Do we follow some specification about post codes values, or are them
> just some random numbers?

Just random - they're all in one place so we can change them pretty easily.

>
>> +/* Output a post code using al - value must be 0 to 0xff */
>> +#ifdef __ASSEMBLY__
>> +#define post_code(value) \
>> +       movb    $value, %al; \
>> +       outb    %al, $POST_PORT
>> +#else
>> +static inline void post_code(int code)
>> +{
>> +       outb(code, POST_PORT);
>> +}
>> +#endif
>> +
>> +#endif
>> diff --git a/board/google/chromebook_link/Kconfig b/board/google/chromebook_link/Kconfig
>> index 975d557..9c715ba 100644
>> --- a/board/google/chromebook_link/Kconfig
>> +++ b/board/google/chromebook_link/Kconfig
>> @@ -12,4 +12,8 @@ config SYS_SOC
>>  config SYS_CONFIG_NAME
>>         default "chromebook_link"
>>
>> +config EARLY_POST_CROS_EC
>> +       bool "Enable early post to Chrome OS EC"
>> +       default y
>> +
>>  endif
>> --
>
> Regards,
> Bin

Regards,
Simon
diff mbox

Patch

diff --git a/arch/x86/cpu/coreboot/coreboot.c b/arch/x86/cpu/coreboot/coreboot.c
index 257faa1..cc7398f 100644
--- a/arch/x86/cpu/coreboot/coreboot.c
+++ b/arch/x86/cpu/coreboot/coreboot.c
@@ -15,6 +15,7 @@ 
 #include <asm/cache.h>
 #include <asm/cpu.h>
 #include <asm/io.h>
+#include <asm/post.h>
 #include <asm/arch-coreboot/tables.h>
 #include <asm/arch-coreboot/sysinfo.h>
 #include <asm/arch/timestamp.h>
@@ -68,7 +69,7 @@  void show_boot_progress(int val)
 		gd->arch.tsc_prev = now;
 	}
 #endif
-	outb(val, 0x80);
+	outb(val, POST_PORT);
 }
 
 int last_stage_init(void)
diff --git a/arch/x86/cpu/start.S b/arch/x86/cpu/start.S
index 7f41475..f62ffeb 100644
--- a/arch/x86/cpu/start.S
+++ b/arch/x86/cpu/start.S
@@ -13,6 +13,7 @@ 
 #include <config.h>
 #include <version.h>
 #include <asm/global_data.h>
+#include <asm/post.h>
 #include <asm/processor.h>
 #include <asm/processor-flags.h>
 #include <generated/generic-asm-offsets.h>
@@ -60,6 +61,28 @@  _start:
 	movw	%ax, %es
 	movw	%ax, %ss
 
+	/* Enable post codes to EC */
+#ifdef CONFIG_EARLY_POST_CROS_EC
+	mov    $0x1b, %ecx
+	rdmsr
+	and    $0x100, %eax
+	test   %eax, %eax
+	je     2f
+
+	mov    $0x8000f8f0, %eax
+	mov    $0xcf8, %dx
+	out    %eax, (%dx)
+	mov    $0xfed1c001, %eax
+	mov    $0xcfc, %dx
+	out    %eax, (%dx)
+	mov    $0xfed1f410, %esp
+	mov    (%esp), %eax
+	and    $0xfffffffb, %eax
+	mov    %eax, (%esp)
+2:
+#endif
+	post_code(POST_START)
+
 	/* Clear the interrupt vectors */
 	lidt	blank_idt_ptr
 
@@ -91,6 +114,7 @@  car_init_ret:
 
 	/* Align global data to 16-byte boundary */
 	andl	$0xfffffff0, %esp
+	post_code(POST_START_STACK)
 
 	/* Zero the global data since it won't happen later */
 	xorl	%eax, %eax
@@ -126,6 +150,7 @@  car_init_ret:
 	call	setup_gdt
 
 	/* Set parameter to board_init_f() to boot flags */
+	post_code(POST_START_DONE)
 	xorl	%eax, %eax
 
 	/* Enter, U-boot! */
diff --git a/arch/x86/include/asm/post.h b/arch/x86/include/asm/post.h
new file mode 100644
index 0000000..3371185
--- /dev/null
+++ b/arch/x86/include/asm/post.h
@@ -0,0 +1,32 @@ 
+/*
+ * Copyright (c) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _post_h
+#define _post_h
+
+/* port to use for post codes */
+#define POST_PORT		0x80
+
+/* post codes which represent various stages of init */
+#define POST_START		0x1e
+#define POST_CAR_START		0x1f
+
+#define POST_START_STACK	0x29
+#define POST_START_DONE		0x2a
+
+/* Output a post code using al - value must be 0 to 0xff */
+#ifdef __ASSEMBLY__
+#define post_code(value) \
+	movb	$value, %al; \
+	outb	%al, $POST_PORT
+#else
+static inline void post_code(int code)
+{
+	outb(code, POST_PORT);
+}
+#endif
+
+#endif
diff --git a/board/google/chromebook_link/Kconfig b/board/google/chromebook_link/Kconfig
index 975d557..9c715ba 100644
--- a/board/google/chromebook_link/Kconfig
+++ b/board/google/chromebook_link/Kconfig
@@ -12,4 +12,8 @@  config SYS_SOC
 config SYS_CONFIG_NAME
 	default "chromebook_link"
 
+config EARLY_POST_CROS_EC
+	bool "Enable early post to Chrome OS EC"
+	default y
+
 endif