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 */ 78 79 /* Stack grows down from top of CAR */ 80 movl $(CONFIG_SYS_CAR_ADDR + CONFIG_SYS_CAR_SIZE), %esp 81 82 /* Reserve space on stack for global data */ 83 subl $GENERATED_GBL_DATA_SIZE, %esp 84 85 /* Align global data to 16-byte boundary */ 86 andl $0xfffffff0, %esp 87 88 /* Zero the global data since it won't happen later */ 89 xorl %eax, %eax 90 movl $GENERATED_GBL_DATA_SIZE, %ecx 91 movl %esp, %edi 92 rep stosb 93 94 /* Setup first parameter to setup_gdt */ 95 movl %esp, %eax 96 97 /* Reserve space for global descriptor table */ 98 subl $X86_GDT_SIZE, %esp 99 100#if defined(CONFIG_SYS_MALLOC_F_LEN) 101 subl $CONFIG_SYS_MALLOC_F_LEN, %esp 102 movl %eax, %edx 103 addl $GD_MALLOC_BASE, %edx 104 movl %esp, (%edx) 105#endif 106 107 /* Align temporary global descriptor table to 16-byte boundary */ 108 andl $0xfffffff0, %esp 109 110 /* Set second parameter to setup_gdt */ 111 movl %esp, %edx 112 113 /* Setup global descriptor table so gd->xyz works */ 114 call setup_gdt 115 116 /* Set parameter to board_init_f() to boot flags */ 117 xorl %eax, %eax 118 movw %bx, %ax 119 120 /* Enter, U-boot! */ 121 call board_init_f 122 123 /* indicate (lack of) progress */ 124 movw $0x85, %ax 125 jmp die 126 127.globl board_init_f_r_trampoline 128.type board_init_f_r_trampoline, @function 129board_init_f_r_trampoline: 130 /* 131 * SDRAM has been initialised, U-Boot code has been copied into 132 * RAM, BSS has been cleared and relocation adjustments have been 133 * made. It is now time to jump into the in-RAM copy of U-Boot 134 * 135 * %eax = Address of top of new stack 136 */ 137 138 /* Stack grows down from top of SDRAM */ 139 movl %eax, %esp 140 141 /* Reserve space on stack for global data */ 142 subl $GENERATED_GBL_DATA_SIZE, %esp 143 144 /* Align global data to 16-byte boundary */ 145 andl $0xfffffff0, %esp 146 147 /* Setup first parameter to memcpy (and setup_gdt) */ 148 movl %esp, %eax 149 150 /* Setup second parameter to memcpy */ 151 fs movl 0, %edx 152 153 /* Set third parameter to memcpy */ 154 movl $GENERATED_GBL_DATA_SIZE, %ecx 155 156 /* Copy global data from CAR to SDRAM stack */ 157 call memcpy 158 159 /* Reserve space for global descriptor table */ 160 subl $X86_GDT_SIZE, %esp 161 162 /* Align global descriptor table to 16-byte boundary */ 163 andl $0xfffffff0, %esp 164 165 /* Set second parameter to setup_gdt */ 166 movl %esp, %edx 167 168 /* Setup global descriptor table so gd->xyz works */ 169 call setup_gdt 170 171 /* Re-enter U-Boot by calling board_init_f_r */ 172 call board_init_f_r 173 174die: 175 hlt 176 jmp die 177 hlt 178 179blank_idt_ptr: 180 .word 0 /* limit */ 181 .long 0 /* base */ 182 183 .p2align 2 /* force 4-byte alignment */ 184 185multiboot_header: 186 /* magic */ 187 .long 0x1BADB002 188 /* flags */ 189 .long (1 << 16) 190 /* checksum */ 191 .long -0x1BADB002 - (1 << 16) 192 /* header addr */ 193 .long multiboot_header - _x86boot_start + CONFIG_SYS_TEXT_BASE 194 /* load addr */ 195 .long CONFIG_SYS_TEXT_BASE 196 /* load end addr */ 197 .long 0 198 /* bss end addr */ 199 .long 0 200 /* entry addr */ 201 .long CONFIG_SYS_TEXT_BASE 202