diff mbox

[U-Boot,v3,07/10] x86: Support a chained-boot development flow

Message ID 1458135883-11813-8-git-send-email-sjg@chromium.org
State Accepted
Commit e5aa8a9b1593f524af07318d4e84352b06a53402
Delegated to: Bin Meng
Headers show

Commit Message

Simon Glass March 16, 2016, 1:44 p.m. UTC
Sometimes it is useful to jump into U-Boot directly from coreboot or UEFI
without any 16-bit init. This can help during development by allowing U-Boot
to avoid doing all the init required by the platform.

U-Boot expects its GDT to be set up correctly by its 16-bit code. If
coreboot doesn't do this (because it hasn't run the payload setup code yet)
then this won't happen.

In this case we cannot rely on the GDT settings. U-Boot will hang or crash
if these are wrong. Provide a development-only option to set up the GDT
correctly. This is just a hack so you can jump to U-Boot from any stage of
coreboot, not just at the end.

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

Changes in v3:
- Add more detail to the commit message and code comments

Changes in v2: None

 arch/x86/cpu/start.S | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 80 insertions(+)

Comments

Bin Meng March 17, 2016, 1:39 a.m. UTC | #1
On Wed, Mar 16, 2016 at 9:44 PM, Simon Glass <sjg@chromium.org> wrote:
> Sometimes it is useful to jump into U-Boot directly from coreboot or UEFI
> without any 16-bit init. This can help during development by allowing U-Boot
> to avoid doing all the init required by the platform.
>
> U-Boot expects its GDT to be set up correctly by its 16-bit code. If
> coreboot doesn't do this (because it hasn't run the payload setup code yet)
> then this won't happen.
>
> In this case we cannot rely on the GDT settings. U-Boot will hang or crash
> if these are wrong. Provide a development-only option to set up the GDT
> correctly. This is just a hack so you can jump to U-Boot from any stage of
> coreboot, not just at the end.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3:
> - Add more detail to the commit message and code comments
>
> Changes in v2: None
>
>  arch/x86/cpu/start.S | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 80 insertions(+)
>

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Bin Meng March 17, 2016, 2:31 a.m. UTC | #2
On Thu, Mar 17, 2016 at 9:39 AM, Bin Meng <bmeng.cn@gmail.com> wrote:
> On Wed, Mar 16, 2016 at 9:44 PM, Simon Glass <sjg@chromium.org> wrote:
>> Sometimes it is useful to jump into U-Boot directly from coreboot or UEFI
>> without any 16-bit init. This can help during development by allowing U-Boot
>> to avoid doing all the init required by the platform.
>>
>> U-Boot expects its GDT to be set up correctly by its 16-bit code. If
>> coreboot doesn't do this (because it hasn't run the payload setup code yet)
>> then this won't happen.
>>
>> In this case we cannot rely on the GDT settings. U-Boot will hang or crash
>> if these are wrong. Provide a development-only option to set up the GDT
>> correctly. This is just a hack so you can jump to U-Boot from any stage of
>> coreboot, not just at the end.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>> Changes in v3:
>> - Add more detail to the commit message and code comments
>>
>> Changes in v2: None
>>
>>  arch/x86/cpu/start.S | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 80 insertions(+)
>>
>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

applied to u-boot-x86, thanks!
diff mbox

Patch

diff --git a/arch/x86/cpu/start.S b/arch/x86/cpu/start.S
index 485868f..a5cba1c 100644
--- a/arch/x86/cpu/start.S
+++ b/arch/x86/cpu/start.S
@@ -18,6 +18,14 @@ 
 #include <generated/generic-asm-offsets.h>
 #include <generated/asm-offsets.h>
 
+/*
+ * Define this to boot U-Boot from a 32-bit program which sets the GDT
+ * differently. This can be used to boot directly from any stage of coreboot,
+ * for example, bypassing the normal payload-loading feature.
+ * This is only useful for development.
+ */
+#undef LOAD_FROM_32_BIT
+
 .section .text
 .code32
 .globl _start
@@ -68,6 +76,10 @@  _start:
 	/* Save table pointer */
 	movl	%ecx, %esi
 
+#ifdef LOAD_FROM_32_BIT
+	lgdt	gdt_ptr2
+#endif
+
 	/* Load the segement registers to match the GDT loaded in start16.S */
 	movl	$(X86_GDT_ENTRY_32BIT_DS * X86_GDT_ENTRY_SIZE), %eax
 	movw	%ax, %fs
@@ -220,3 +232,71 @@  multiboot_header:
 	.long	0
 	/* entry addr */
 	.long	CONFIG_SYS_TEXT_BASE
+
+#ifdef LOAD_FROM_32_BIT
+	/*
+	 * The following Global Descriptor Table is just enough to get us into
+	 * 'Flat Protected Mode' - It will be discarded as soon as the final
+	 * GDT is setup in a safe location in RAM
+	 */
+gdt_ptr2:
+	.word	0x1f		/* limit (31 bytes = 4 GDT entries - 1) */
+	.long	gdt_rom2	/* base */
+
+	/* Some CPUs are picky about GDT alignment... */
+	.align	16
+.globl gdt_rom2
+gdt_rom2:
+	/*
+	 * The GDT table ...
+	 *
+	 *	 Selector	Type
+	 *	 0x00		NULL
+	 *	 0x08		Unused
+	 *	 0x10		32bit code
+	 *	 0x18		32bit data/stack
+	 */
+	/* The NULL Desciptor - Mandatory */
+	.word	0x0000		/* limit_low */
+	.word	0x0000		/* base_low */
+	.byte	0x00		/* base_middle */
+	.byte	0x00		/* access */
+	.byte	0x00		/* flags + limit_high */
+	.byte	0x00		/* base_high */
+
+	/* Unused Desciptor - (matches Linux) */
+	.word	0x0000		/* limit_low */
+	.word	0x0000		/* base_low */
+	.byte	0x00		/* base_middle */
+	.byte	0x00		/* access */
+	.byte	0x00		/* flags + limit_high */
+	.byte	0x00		/* base_high */
+
+	/*
+	 * The Code Segment Descriptor:
+	 * - Base   = 0x00000000
+	 * - Size   = 4GB
+	 * - Access = Present, Ring 0, Exec (Code), Readable
+	 * - Flags  = 4kB Granularity, 32-bit
+	 */
+	.word	0xffff		/* limit_low */
+	.word	0x0000		/* base_low */
+	.byte	0x00		/* base_middle */
+	.byte	0x9b		/* access */
+	.byte	0xcf		/* flags + limit_high */
+	.byte	0x00		/* base_high */
+
+	/*
+	 * The Data Segment Descriptor:
+	 * - Base   = 0x00000000
+	 * - Size   = 4GB
+	 * - Access = Present, Ring 0, Non-Exec (Data), Writable
+	 * - Flags  = 4kB Granularity, 32-bit
+	 */
+	.word	0xffff		/* limit_low */
+	.word	0x0000		/* base_low */
+	.byte	0x00		/* base_middle */
+	.byte	0x93		/* access */
+	.byte	0xcf		/* flags + limit_high */
+	.byte	0x00		/* base_high */
+#endif