1fea25720SGraeme Russ/* 2fea25720SGraeme Russ * U-boot - x86 Startup Code 3fea25720SGraeme Russ * 4fea25720SGraeme Russ * (C) Copyright 2008-2011 5fea25720SGraeme Russ * Graeme Russ, <graeme.russ@gmail.com> 6fea25720SGraeme Russ * 7fea25720SGraeme Russ * (C) Copyright 2002,2003 8fa82f871SAlbert ARIBAUD * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> 9fea25720SGraeme Russ * 10fea25720SGraeme Russ * See file CREDITS for list of people who contributed to this 11fea25720SGraeme Russ * project. 12fea25720SGraeme Russ * 13fea25720SGraeme Russ * This program is free software; you can redistribute it and/or 14fea25720SGraeme Russ * modify it under the terms of the GNU General Public License as 15fea25720SGraeme Russ * published by the Free Software Foundation; either version 2 of 16fea25720SGraeme Russ * the License, or (at your option) any later version. 17fea25720SGraeme Russ * 18fea25720SGraeme Russ * This program is distributed in the hope that it will be useful, 19fea25720SGraeme Russ * but WITHOUT ANY WARRANTY; without even the implied warranty of 20fea25720SGraeme Russ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21fea25720SGraeme Russ * GNU General Public License for more details. 22fea25720SGraeme Russ * 23fea25720SGraeme Russ * You should have received a copy of the GNU General Public License 24fea25720SGraeme Russ * along with this program; if not, write to the Free Software 25fea25720SGraeme Russ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 26fea25720SGraeme Russ * MA 02111-1307 USA 27fea25720SGraeme Russ */ 28fea25720SGraeme Russ 29fea25720SGraeme Russ#include <asm/global_data.h> 30fea25720SGraeme Russ#include <asm/processor-flags.h> 31fea25720SGraeme Russ 32fea25720SGraeme Russ#define BOOT_SEG 0xffff0000 /* linear segment of boot code */ 33fea25720SGraeme Russ#define a32 .byte 0x67; 34fea25720SGraeme Russ#define o32 .byte 0x66; 35fea25720SGraeme Russ 36fea25720SGraeme Russ.section .start16, "ax" 37fea25720SGraeme Russ.code16 38fea25720SGraeme Russ.globl start16 39fea25720SGraeme Russstart16: 40*91d82a29SGabe Black /* Set the Cold Boot / Hard Reset flag */ 41*91d82a29SGabe Black movl $GD_FLG_COLD_BOOT, %ebx 42*91d82a29SGabe Black 43fea25720SGraeme Russ /* 44fea25720SGraeme Russ * First we let the BSP do some early initialization 45fea25720SGraeme Russ * this code have to map the flash to its final position 46fea25720SGraeme Russ */ 47fea25720SGraeme Russ jmp board_init16 48fea25720SGraeme Russ.globl board_init16_ret 49fea25720SGraeme Russboard_init16_ret: 50fea25720SGraeme Russ 51fea25720SGraeme Russ /* Turn of cache (this might require a 486-class CPU) */ 52fea25720SGraeme Russ movl %cr0, %eax 537b3d5380SOndrej Kupka orl $(X86_CR0_NW | X86_CR0_CD), %eax 54fea25720SGraeme Russ movl %eax, %cr0 55fea25720SGraeme Russ wbinvd 56fea25720SGraeme Russ 57fea25720SGraeme Russ /* load the temporary Global Descriptor Table */ 58fea25720SGraeme Russo32 cs lidt idt_ptr 59fea25720SGraeme Russo32 cs lgdt gdt_ptr 60fea25720SGraeme Russ 61fea25720SGraeme Russ /* Now, we enter protected mode */ 62fea25720SGraeme Russ movl %cr0, %eax 63fea25720SGraeme Russ orl $X86_CR0_PE, %eax 64fea25720SGraeme Russ movl %eax, %cr0 65fea25720SGraeme Russ 66fea25720SGraeme Russ /* Flush the prefetch queue */ 67fea25720SGraeme Russ jmp ff 68fea25720SGraeme Russff: 69fea25720SGraeme Russ /* Finally jump to the 32bit initialization code */ 70fea25720SGraeme Russ movw $code32start, %ax 71fea25720SGraeme Russ movw %ax, %bp 72fea25720SGraeme Russo32 cs ljmp *(%bp) 73fea25720SGraeme Russ 74fea25720SGraeme Russ /* 48-bit far pointer */ 75fea25720SGraeme Russcode32start: 76fea25720SGraeme Russ .long _start /* offset */ 77fea25720SGraeme Russ .word 0x10 /* segment */ 78fea25720SGraeme Russ 79fea25720SGraeme Russidt_ptr: 80fea25720SGraeme Russ .word 0 /* limit */ 81fea25720SGraeme Russ .long 0 /* base */ 82fea25720SGraeme Russ 83fea25720SGraeme Russ/* 84fea25720SGraeme Russ * The following Global Descriptor Table is just enough to get us into 85fea25720SGraeme Russ * 'Flat Protected Mode' - It will be discarded as soon as the final 86fea25720SGraeme Russ * GDT is setup in a safe location in RAM 87fea25720SGraeme Russ */ 88fea25720SGraeme Russgdt_ptr: 89fea25720SGraeme Russ .word 0x20 /* limit (32 bytes = 4 GDT entries) */ 90fea25720SGraeme Russ .long BOOT_SEG + gdt /* base */ 91fea25720SGraeme Russ 9258c7a675SGraeme Russ/* Some CPUs are picky about GDT alignment... */ 9358c7a675SGraeme Russ.align 16 9458c7a675SGraeme Russgdt: 9558c7a675SGraeme Russ /* 9658c7a675SGraeme Russ * The GDT table ... 97fea25720SGraeme Russ * 98fea25720SGraeme Russ * Selector Type 99fea25720SGraeme Russ * 0x00 NULL 100fea25720SGraeme Russ * 0x08 Unused 101fea25720SGraeme Russ * 0x10 32bit code 102fea25720SGraeme Russ * 0x18 32bit data/stack 103fea25720SGraeme Russ */ 10458c7a675SGraeme Russ /* The NULL Desciptor - Mandatory */ 10558c7a675SGraeme Russ .word 0x0000 /* limit_low */ 10658c7a675SGraeme Russ .word 0x0000 /* base_low */ 10758c7a675SGraeme Russ .byte 0x00 /* base_middle */ 10858c7a675SGraeme Russ .byte 0x00 /* access */ 10958c7a675SGraeme Russ .byte 0x00 /* flags + limit_high */ 11058c7a675SGraeme Russ .byte 0x00 /* base_high */ 111fea25720SGraeme Russ 11258c7a675SGraeme Russ /* Unused Desciptor - (matches Linux) */ 11358c7a675SGraeme Russ .word 0x0000 /* limit_low */ 11458c7a675SGraeme Russ .word 0x0000 /* base_low */ 11558c7a675SGraeme Russ .byte 0x00 /* base_middle */ 11658c7a675SGraeme Russ .byte 0x00 /* access */ 11758c7a675SGraeme Russ .byte 0x00 /* flags + limit_high */ 11858c7a675SGraeme Russ .byte 0x00 /* base_high */ 119fea25720SGraeme Russ 12058c7a675SGraeme Russ /* 12158c7a675SGraeme Russ * The Code Segment Descriptor: 12258c7a675SGraeme Russ * - Base = 0x00000000 12358c7a675SGraeme Russ * - Size = 4GB 12458c7a675SGraeme Russ * - Access = Present, Ring 0, Exec (Code), Readable 12558c7a675SGraeme Russ * - Flags = 4kB Granularity, 32-bit 12658c7a675SGraeme Russ */ 12758c7a675SGraeme Russ .word 0xffff /* limit_low */ 12858c7a675SGraeme Russ .word 0x0000 /* base_low */ 12958c7a675SGraeme Russ .byte 0x00 /* base_middle */ 13058c7a675SGraeme Russ .byte 0x9b /* access */ 13158c7a675SGraeme Russ .byte 0xcf /* flags + limit_high */ 13258c7a675SGraeme Russ .byte 0x00 /* base_high */ 133fea25720SGraeme Russ 13458c7a675SGraeme Russ /* 13558c7a675SGraeme Russ * The Data Segment Descriptor: 13658c7a675SGraeme Russ * - Base = 0x00000000 13758c7a675SGraeme Russ * - Size = 4GB 13858c7a675SGraeme Russ * - Access = Present, Ring 0, Non-Exec (Data), Writable 13958c7a675SGraeme Russ * - Flags = 4kB Granularity, 32-bit 14058c7a675SGraeme Russ */ 14158c7a675SGraeme Russ .word 0xffff /* limit_low */ 14258c7a675SGraeme Russ .word 0x0000 /* base_low */ 14358c7a675SGraeme Russ .byte 0x00 /* base_middle */ 14458c7a675SGraeme Russ .byte 0x93 /* access */ 14558c7a675SGraeme Russ .byte 0xcf /* flags + limit_high */ 14658c7a675SGraeme Russ .byte 0x00 /* base_high */ 147