common: Drop init.h from common header
[oweals/u-boot.git] / arch / x86 / cpu / start.S
index 485868ff5769ecca47fa01e0028eca14ac4ccdeb..01524635e9c82d9a498653605dc36d2107ea8d90 100644 (file)
@@ -1,13 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  *  U-Boot - x86 Startup Code
  *
+ * This is always the first code to run from the U-Boot source. To spell it out:
+ *
+ * 1. When TPL (Tertiary Program Loader) is enabled, the boot flow is
+ * TPL->SPL->U-Boot and this file is used for TPL. Then start_from_tpl.S is used
+ * for SPL and start_from_spl.S is used for U-Boot proper.
+ *
+ * 2. When SPL (Secondary Program Loader) is enabled, but not TPL, the boot
+ * flow is SPL->U-Boot and this file is used for SPL. Then start_from_spl.S is
+ * used for U-Boot proper.
+ *
+ * 3. When neither TPL nor SPL is used, this file is used for U-Boot proper.
+ *
  * (C) Copyright 2008-2011
  * Graeme Russ, <graeme.russ@gmail.com>
  *
  * (C) Copyright 2002
  * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se>
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <config.h>
@@ -17,8 +28,9 @@
 #include <asm/processor-flags.h>
 #include <generated/generic-asm-offsets.h>
 #include <generated/asm-offsets.h>
+#include <linux/linkage.h>
 
-.section .text
+.section .text.start
 .code32
 .globl _start
 .type _start, @function
@@ -40,9 +52,6 @@ _x86boot_start:
        movl    %eax, %cr0
        wbinvd
 
-       /* Tell 32-bit code it is being entered from an in-RAM copy */
-       movl    $GD_FLG_WARM_BOOT, %ebx
-
        /*
         * Zero the BIST (Built-In Self Test) value since we don't have it.
         * It must be 0 or the previous loader would have reported an error.
@@ -55,11 +64,7 @@ _x86boot_start:
        .align  4
        .long   0x12345678
 _start:
-       /*
-        * This is the 32-bit cold-reset entry point, coming from start16.
-        * Set %ebx to GD_FLG_COLD_BOOT to indicate this.
-        */
-       movl    $GD_FLG_COLD_BOOT, %ebx
+       /* This is the 32-bit cold-reset entry point, coming from start16 */
 
        /* Save BIST */
        movl    %eax, %ebp
@@ -68,6 +73,10 @@ _start:
        /* Save table pointer */
        movl    %ecx, %esi
 
+#ifdef CONFIG_X86_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
@@ -93,7 +102,7 @@ early_board_init_ret:
        jmp     car_init
 .globl car_init_ret
 car_init_ret:
-#ifndef CONFIG_HAVE_FSP
+#ifdef CONFIG_USE_CAR
        /*
         * We now have CONFIG_SYS_CAR_SIZE bytes of Cache-As-RAM (or SRAM,
         * or fully initialised SDRAM - we really don't care which)
@@ -133,12 +142,13 @@ car_init_ret:
 
        /* Get address of global_data */
        mov     %fs:0, %edx
-#ifdef CONFIG_HAVE_FSP
+#if defined(CONFIG_USE_HOB) && !defined(CONFIG_USE_CAR)
        /* Store the HOB list if we have one */
        test    %esi, %esi
        jz      skip_hob
        movl    %esi, GD_HOB_LIST(%edx)
 
+#ifdef CONFIG_HAVE_FSP
        /*
         * After fsp_init() returns, the stack has already been switched to a
         * place within system memory as defined by CONFIG_FSP_TEMP_RAM_ADDR.
@@ -147,6 +157,7 @@ car_init_ret:
         */
        subl    $CONFIG_FSP_SYS_MALLOC_F_LEN, %esp
        movl    %esp, GD_MALLOC_BASE(%edx)
+#endif
 skip_hob:
 #else
        /* Store table pointer */
@@ -181,21 +192,33 @@ board_init_f_r_trampoline:
        movl    %eax, %esp
 
        /* See if we need to disable CAR */
-.weak  car_uninit
-       movl    $car_uninit, %eax
-       cmpl    $0, %eax
-       jz      1f
-
        call    car_uninit
-1:
+
        /* Re-enter U-Boot by calling board_init_f_r() */
        call    board_init_f_r
 
+#ifdef CONFIG_TPL
+.globl jump_to_spl
+.type jump_to_spl, @function
+jump_to_spl:
+       /* Reset stack to the top of CAR space */
+       movl    $(CONFIG_SYS_CAR_ADDR + CONFIG_SYS_CAR_SIZE - 4), %esp
+#ifdef CONFIG_DCACHE_RAM_MRC_VAR_SIZE
+       subl    $CONFIG_DCACHE_RAM_MRC_VAR_SIZE, %esp
+#endif
+
+       jmp     *%eax
+#endif
+
 die:
        hlt
        jmp     die
        hlt
 
+WEAK(car_uninit)
+       ret
+ENDPROC(car_uninit)
+
 blank_idt_ptr:
        .word   0               /* limit */
        .long   0               /* base */
@@ -220,3 +243,71 @@ multiboot_header:
        .long   0
        /* entry addr */
        .long   CONFIG_SYS_TEXT_BASE
+
+#ifdef CONFIG_X86_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