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 53 /* Load the segement registes to match the gdt loaded in start16.S */ 54 movl $(X86_GDT_ENTRY_32BIT_DS * X86_GDT_ENTRY_SIZE), %eax 55 movw %ax, %fs 56 movw %ax, %ds 57 movw %ax, %gs 58 movw %ax, %es 59 movw %ax, %ss 60 61 /* Clear the interrupt vectors */ 62 lidt blank_idt_ptr 63 64 /* Early platform init (setup gpio, etc ) */ 65 jmp early_board_init 66.globl early_board_init_ret 67early_board_init_ret: 68 69 /* Initialise Cache-As-RAM */ 70 jmp car_init 71.globl car_init_ret 72car_init_ret: 73 /* 74 * We now have CONFIG_SYS_CAR_SIZE bytes of Cache-As-RAM (or SRAM, 75 * or fully initialised SDRAM - we really don't care which) 76 * starting at CONFIG_SYS_CAR_ADDR to be used as a temporary stack 77 * and early malloc area. 78 * 79 * Stack grows down from top of CAR. We have: 80 * 81 * top-> CONFIG_SYS_CAR_ADDR + CONFIG_SYS_CAR_SIZE 82 * global_data 83 * x86 global descriptor table 84 * early malloc area 85 * stack 86 * bottom-> CONFIG_SYS_CAR_ADDR 87 */ 88 89 /* Stack grows down from top of CAR */ 90 movl $(CONFIG_SYS_CAR_ADDR + CONFIG_SYS_CAR_SIZE), %esp 91 92 /* Reserve space on stack for global data */ 93 subl $GENERATED_GBL_DATA_SIZE, %esp 94 95 /* Align global data to 16-byte boundary */ 96 andl $0xfffffff0, %esp 97 98 /* Zero the global data since it won't happen later */ 99 xorl %eax, %eax 100 movl $GENERATED_GBL_DATA_SIZE, %ecx 101 movl %esp, %edi 102 rep stosb 103 104 /* Setup first parameter to setup_gdt, pointer to global_data */ 105 movl %esp, %eax 106 107 /* Reserve space for global descriptor table */ 108 subl $X86_GDT_SIZE, %esp 109 110 /* Align temporary global descriptor table to 16-byte boundary */ 111 andl $0xfffffff0, %esp 112 movl %esp, %ecx 113 114#if defined(CONFIG_SYS_MALLOC_F_LEN) 115 subl $CONFIG_SYS_MALLOC_F_LEN, %esp 116 movl %eax, %edx 117 addl $GD_MALLOC_BASE, %edx 118 movl %esp, (%edx) 119#endif 120 121 /* Align temporary global descriptor table to 16-byte boundary */ 122 andl $0xfffffff0, %esp 123 124 /* Set second parameter to setup_gdt */ 125 movl %ecx, %edx 126 127 /* Setup global descriptor table so gd->xyz works */ 128 call setup_gdt 129 130 /* Set parameter to board_init_f() to boot flags */ 131 xorl %eax, %eax 132 133 /* Enter, U-boot! */ 134 call board_init_f 135 136 /* indicate (lack of) progress */ 137 movw $0x85, %ax 138 jmp die 139 140.globl board_init_f_r_trampoline 141.type board_init_f_r_trampoline, @function 142board_init_f_r_trampoline: 143 /* 144 * SDRAM has been initialised, U-Boot code has been copied into 145 * RAM, BSS has been cleared and relocation adjustments have been 146 * made. It is now time to jump into the in-RAM copy of U-Boot 147 * 148 * %eax = Address of top of new stack 149 */ 150 151 /* Stack grows down from top of SDRAM */ 152 movl %eax, %esp 153 154 /* Reserve space on stack for global data */ 155 subl $GENERATED_GBL_DATA_SIZE, %esp 156 157 /* Align global data to 16-byte boundary */ 158 andl $0xfffffff0, %esp 159 160 /* Setup first parameter to memcpy (and setup_gdt) */ 161 movl %esp, %eax 162 163 /* Setup second parameter to memcpy */ 164 fs movl 0, %edx 165 166 /* Set third parameter to memcpy */ 167 movl $GENERATED_GBL_DATA_SIZE, %ecx 168 169 /* Copy global data from CAR to SDRAM stack */ 170 call memcpy 171 172 /* Reserve space for global descriptor table */ 173 subl $X86_GDT_SIZE, %esp 174 175 /* Align global descriptor table to 16-byte boundary */ 176 andl $0xfffffff0, %esp 177 178 /* Set second parameter to setup_gdt */ 179 movl %esp, %edx 180 181 /* Setup global descriptor table so gd->xyz works */ 182 call setup_gdt 183 184 /* Re-enter U-Boot by calling board_init_f_r */ 185 call board_init_f_r 186 187die: 188 hlt 189 jmp die 190 hlt 191 192blank_idt_ptr: 193 .word 0 /* limit */ 194 .long 0 /* base */ 195 196 .p2align 2 /* force 4-byte alignment */ 197 198multiboot_header: 199 /* magic */ 200 .long 0x1BADB002 201 /* flags */ 202 .long (1 << 16) 203 /* checksum */ 204 .long -0x1BADB002 - (1 << 16) 205 /* header addr */ 206 .long multiboot_header - _x86boot_start + CONFIG_SYS_TEXT_BASE 207 /* load addr */ 208 .long CONFIG_SYS_TEXT_BASE 209 /* load end addr */ 210 .long 0 211 /* bss end addr */ 212 .long 0 213 /* entry addr */ 214 .long CONFIG_SYS_TEXT_BASE 215