1/* 2 * U-boot - x86 Startup Code 3 * 4 * (C) Copyright 2008-2011 5 * Graeme Russ, <graeme.russ@gmail.com> 6 * 7 * (C) Copyright 2002 8 * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> 9 * 10 * SPDX-License-Identifier: GPL-2.0+ 11 */ 12 13#include <config.h> 14#include <version.h> 15#include <asm/global_data.h> 16#include <asm/processor.h> 17#include <asm/processor-flags.h> 18#include <generated/generic-asm-offsets.h> 19 20.section .text 21.code32 22.globl _start 23.type _start, @function 24.globl _x86boot_start 25_x86boot_start: 26 /* 27 * This is the fail safe 32-bit bootstrap entry point. The 28 * following code is not executed from a cold-reset (actually, a 29 * lot of it is, but from real-mode after cold reset. It is 30 * repeated here to put the board into a state as close to cold 31 * reset as necessary) 32 */ 33 cli 34 cld 35 36 /* Turn off cache (this might require a 486-class CPU) */ 37 movl %cr0, %eax 38 orl $(X86_CR0_NW | X86_CR0_CD), %eax 39 movl %eax, %cr0 40 wbinvd 41 42 /* Tell 32-bit code it is being entered from an in-RAM copy */ 43 movw $GD_FLG_WARM_BOOT, %bx 44 jmp 1f 45_start: 46 /* 47 * This is the 32-bit cold-reset entry point. Initialize %bx to 0 48 * in case we're preceeded by some sort of boot stub. 49 */ 50 movw $GD_FLG_COLD_BOOT, %bx 511: 52 /* Save BIST */ 53 movl %eax, %ebp 54 55 /* Load the segement registes to match the gdt loaded in start16.S */ 56 movl $(X86_GDT_ENTRY_32BIT_DS * X86_GDT_ENTRY_SIZE), %eax 57 movw %ax, %fs 58 movw %ax, %ds 59 movw %ax, %gs 60 movw %ax, %es 61 movw %ax, %ss 62 63 /* Clear the interrupt vectors */ 64 lidt blank_idt_ptr 65 66 /* Early platform init (setup gpio, etc ) */ 67 jmp early_board_init 68.globl early_board_init_ret 69early_board_init_ret: 70 71 /* Initialise Cache-As-RAM */ 72 jmp car_init 73.globl car_init_ret 74car_init_ret: 75 /* 76 * We now have CONFIG_SYS_CAR_SIZE bytes of Cache-As-RAM (or SRAM, 77 * or fully initialised SDRAM - we really don't care which) 78 * starting at CONFIG_SYS_CAR_ADDR to be used as a temporary stack 79 * and early malloc area. 80 * 81 * Stack grows down from top of CAR. We have: 82 * 83 * top-> CONFIG_SYS_CAR_ADDR + CONFIG_SYS_CAR_SIZE 84 * global_data 85 * x86 global descriptor table 86 * early malloc area 87 * stack 88 * bottom-> CONFIG_SYS_CAR_ADDR 89 */ 90 91 /* Stack grows down from top of CAR */ 92 movl $(CONFIG_SYS_CAR_ADDR + CONFIG_SYS_CAR_SIZE), %esp 93 94 /* Reserve space on stack for global data */ 95 subl $GENERATED_GBL_DATA_SIZE, %esp 96 97 /* Align global data to 16-byte boundary */ 98 andl $0xfffffff0, %esp 99 100 /* Zero the global data since it won't happen later */ 101 xorl %eax, %eax 102 movl $GENERATED_GBL_DATA_SIZE, %ecx 103 movl %esp, %edi 104 rep stosb 105 106 /* Setup first parameter to setup_gdt, pointer to global_data */ 107 movl %esp, %eax 108 109 /* Reserve space for global descriptor table */ 110 subl $X86_GDT_SIZE, %esp 111 112 /* Align temporary global descriptor table to 16-byte boundary */ 113 andl $0xfffffff0, %esp 114 movl %esp, %ecx 115 116#if defined(CONFIG_SYS_MALLOC_F_LEN) 117 subl $CONFIG_SYS_MALLOC_F_LEN, %esp 118 movl %eax, %edx 119 addl $GD_MALLOC_BASE, %edx 120 movl %esp, (%edx) 121#endif 122 /* Store BIST */ 123 movl %eax, %edx 124 addl $GD_BIST, %edx 125 movl %ebp, (%edx) 126 127 /* Set second parameter to setup_gdt */ 128 movl %ecx, %edx 129 130 /* Setup global descriptor table so gd->xyz works */ 131 call setup_gdt 132 133 /* Set parameter to board_init_f() to boot flags */ 134 xorl %eax, %eax 135 136 /* Enter, U-boot! */ 137 call board_init_f 138 139 /* indicate (lack of) progress */ 140 movw $0x85, %ax 141 jmp die 142 143.globl board_init_f_r_trampoline 144.type board_init_f_r_trampoline, @function 145board_init_f_r_trampoline: 146 /* 147 * SDRAM has been initialised, U-Boot code has been copied into 148 * RAM, BSS has been cleared and relocation adjustments have been 149 * made. It is now time to jump into the in-RAM copy of U-Boot 150 * 151 * %eax = Address of top of new stack 152 */ 153 154 /* Stack grows down from top of SDRAM */ 155 movl %eax, %esp 156 157 /* Reserve space on stack for global data */ 158 subl $GENERATED_GBL_DATA_SIZE, %esp 159 160 /* Align global data to 16-byte boundary */ 161 andl $0xfffffff0, %esp 162 163 /* Setup first parameter to memcpy (and setup_gdt) */ 164 movl %esp, %eax 165 166 /* Setup second parameter to memcpy */ 167 fs movl 0, %edx 168 169 /* Set third parameter to memcpy */ 170 movl $GENERATED_GBL_DATA_SIZE, %ecx 171 172 /* Copy global data from CAR to SDRAM stack */ 173 call memcpy 174 175 /* Reserve space for global descriptor table */ 176 subl $X86_GDT_SIZE, %esp 177 178 /* Align global descriptor table to 16-byte boundary */ 179 andl $0xfffffff0, %esp 180 181 /* Set second parameter to setup_gdt */ 182 movl %esp, %edx 183 184 /* Setup global descriptor table so gd->xyz works */ 185 call setup_gdt 186 187 /* Re-enter U-Boot by calling board_init_f_r */ 188 call board_init_f_r 189 190die: 191 hlt 192 jmp die 193 hlt 194 195blank_idt_ptr: 196 .word 0 /* limit */ 197 .long 0 /* base */ 198 199 .p2align 2 /* force 4-byte alignment */ 200 201multiboot_header: 202 /* magic */ 203 .long 0x1BADB002 204 /* flags */ 205 .long (1 << 16) 206 /* checksum */ 207 .long -0x1BADB002 - (1 << 16) 208 /* header addr */ 209 .long multiboot_header - _x86boot_start + CONFIG_SYS_TEXT_BASE 210 /* load addr */ 211 .long CONFIG_SYS_TEXT_BASE 212 /* load end addr */ 213 .long 0 214 /* bss end addr */ 215 .long 0 216 /* entry addr */ 217 .long CONFIG_SYS_TEXT_BASE 218