]> git.sur5r.net Git - u-boot/blobdiff - arch/x86/cpu/start.S
Merge branch 'master' of git://git.denx.de/u-boot-samsung
[u-boot] / arch / x86 / cpu / start.S
index a0dec39abeaabbd66cb439418e5a0e9ab9ae44c0..a5cba1cf2a766680e3e1b8ab6290bee2aa8a0191 100644 (file)
 #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
@@ -42,6 +50,13 @@ _x86boot_start:
 
        /* 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.
+        */
+       movl    $0, %ebp
+
        jmp     1f
 
        /* Add a way for tools to discover the _start entry point */
@@ -53,9 +68,17 @@ _start:
         * Set %ebx to GD_FLG_COLD_BOOT to indicate this.
         */
        movl    $GD_FLG_COLD_BOOT, %ebx
-1:
+
        /* Save BIST */
        movl    %eax, %ebp
+1:
+
+       /* 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
@@ -93,8 +116,7 @@ car_init_ret:
         *
         * top-> CONFIG_SYS_CAR_ADDR + CONFIG_SYS_CAR_SIZE
         *      MRC area
-        *      global_data
-        *      x86 global descriptor table
+        *      global_data with x86 global descriptor table
         *      early malloc area
         *      stack
         * bottom-> CONFIG_SYS_CAR_ADDR
@@ -105,62 +127,45 @@ car_init_ret:
 #endif
 #else
        /*
-        * When we get here after car_init(), esp points to a temporary stack
-        * and esi holds the HOB list address returned by the FSP.
+        * U-Boot enters here twice. For the first time it comes from
+        * car_init_done() with esp points to a temporary stack and esi
+        * set to zero. For the second time it comes from fsp_init_done()
+        * with esi holding the HOB list address returned by the FSP.
         */
 #endif
+       /* Set up global data */
+       mov     %esp, %eax
+       call    board_init_f_alloc_reserve
+       mov     %eax, %esp
+       call    board_init_f_init_reserve
+
+#ifdef CONFIG_DEBUG_UART
+       call    debug_uart_init
+#endif
 
-       /* Reserve space on stack for global data */
-       subl    $GENERATED_GBL_DATA_SIZE, %esp
-
-       /* 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
-       movl    $GENERATED_GBL_DATA_SIZE, %ecx
-       movl    %esp, %edi
-       rep     stosb
-
+       /* Get address of global_data */
+       mov     %fs:0, %edx
 #ifdef CONFIG_HAVE_FSP
+       /* Store the HOB list if we have one */
        test    %esi, %esi
        jz      skip_hob
+       movl    %esi, GD_HOB_LIST(%edx)
 
-       /* Store HOB list */
-       movl    %esp, %edx
-       addl    $GD_HOB_LIST, %edx
-       movl    %esi, (%edx)
-
+       /*
+        * After fsp_init() returns, the stack has already been switched to a
+        * place within system memory as defined by CONFIG_FSP_TEMP_RAM_ADDR.
+        * Enlarge the size of malloc() pool before relocation since we have
+        * plenty of memory now.
+        */
+       subl    $CONFIG_FSP_SYS_MALLOC_F_LEN, %esp
+       movl    %esp, GD_MALLOC_BASE(%edx)
 skip_hob:
+#else
+       /* Store table pointer */
+       movl    %esi, GD_TABLE(%edx)
 #endif
-       /* Setup first parameter to setup_gdt, pointer to global_data */
-       movl    %esp, %eax
-
-       /* Reserve space for global descriptor table */
-       subl    $X86_GDT_SIZE, %esp
-
-       /* Align temporary global descriptor table to 16-byte boundary */
-       andl    $0xfffffff0, %esp
-       movl    %esp, %ecx
-
-#if defined(CONFIG_SYS_MALLOC_F_LEN)
-       /* Set up the pre-relocation malloc pool */
-       subl    $CONFIG_SYS_MALLOC_F_LEN, %esp
-       movl    %eax, %edx
-       addl    $GD_MALLOC_BASE, %edx
-       movl    %esp, (%edx)
-#endif
-       /* Store BIST into global_data */
-       movl    %eax, %edx
-       addl    $GD_BIST, %edx
-       movl    %ebp, (%edx)
-
-       /* Set second parameter to setup_gdt() */
-       movl    %ecx, %edx
-
-       /* Setup global descriptor table so gd->xyz works */
-       call    setup_gdt
+       /* Store BIST */
+       movl    %ebp, GD_BIST(%edx)
 
        /* Set parameter to board_init_f() to boot flags */
        post_code(POST_START_DONE)
@@ -187,37 +192,7 @@ board_init_f_r_trampoline:
        /* Stack grows down from top of SDRAM */
        movl    %eax, %esp
 
-       /* Reserve space on stack for global data */
-       subl    $GENERATED_GBL_DATA_SIZE, %esp
-
-       /* Align global data to 16-byte boundary */
-       andl    $0xfffffff0, %esp
-
-       /* Setup first parameter to memcpy() and setup_gdt() */
-       movl    %esp, %eax
-
-       /* Setup second parameter to memcpy() */
-       fs movl 0, %edx
-
-       /* Set third parameter to memcpy() */
-       movl    $GENERATED_GBL_DATA_SIZE, %ecx
-
-       /* Copy global data from CAR to SDRAM stack */
-       call    memcpy
-
-       /* Reserve space for global descriptor table */
-       subl    $X86_GDT_SIZE, %esp
-
-       /* Align global descriptor table to 16-byte boundary */
-       andl    $0xfffffff0, %esp
-
-       /* Set second parameter to setup_gdt() */
-       movl    %esp, %edx
-
-       /* Setup global descriptor table so gd->xyz works */
-       call    setup_gdt
-
-       /* Set if we need to disable CAR */
+       /* See if we need to disable CAR */
 .weak  car_uninit
        movl    $car_uninit, %eax
        cmpl    $0, %eax
@@ -257,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