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