Home | History | Annotate | Download | only in cpu
      1 /* SPDX-License-Identifier: GPL-2.0+ */
      2 /*
      3  *  U-Boot - x86 Startup Code
      4  *
      5  * (C) Copyright 2008-2011
      6  * Graeme Russ, <graeme.russ (at) gmail.com>
      7  *
      8  * (C) Copyright 2002,2003
      9  * Daniel Engstrm, Omicron Ceti AB, <daniel (at) omicron.se>
     10  */
     11 
     12 #include <asm/global_data.h>
     13 #include <asm/processor-flags.h>
     14 
     15 #define BOOT_SEG	0xffff0000	/* linear segment of boot code */
     16 #define a32		.byte 0x67;
     17 #define o32		.byte 0x66;
     18 
     19 .section .start16, "ax"
     20 .code16
     21 .globl start16
     22 start16:
     23 	/* Save BIST */
     24 	movl	%eax, %ecx
     25 
     26 	/* Set the Cold Boot / Hard Reset flag */
     27 	movl	$GD_FLG_COLD_BOOT, %ebx
     28 
     29 	xorl	%eax, %eax
     30 	movl	%eax, %cr3	/* Invalidate TLB */
     31 
     32 	/* Turn off cache (this might require a 486-class CPU) */
     33 	movl	%cr0, %eax
     34 	orl	$(X86_CR0_NW | X86_CR0_CD), %eax
     35 	movl	%eax, %cr0
     36 	wbinvd
     37 
     38 	/* load the temporary Global Descriptor Table */
     39 o32 cs	lidt	idt_ptr
     40 o32 cs	lgdt	gdt_ptr
     41 
     42 	/* Now, we enter protected mode */
     43 	movl	%cr0, %eax
     44 	orl	$X86_CR0_PE, %eax
     45 	movl	%eax, %cr0
     46 
     47 	/* Flush the prefetch queue */
     48 	jmp	ff
     49 ff:
     50 
     51 	/* Finally restore BIST and jump to the 32-bit initialization code */
     52 	movw	$code32start, %ax
     53 	movw	%ax, %bp
     54 	movl	%ecx, %eax
     55 o32 cs	ljmp	*(%bp)
     56 
     57 	/* 48-bit far pointer */
     58 code32start:
     59 	.long	_start		/* offset */
     60 	.word	0x10		/* segment */
     61 
     62 idt_ptr:
     63 	.word	0		/* limit */
     64 	.long	0		/* base */
     65 
     66 	/*
     67 	 * The following Global Descriptor Table is just enough to get us into
     68 	 * 'Flat Protected Mode' - It will be discarded as soon as the final
     69 	 * GDT is setup in a safe location in RAM
     70 	 */
     71 gdt_ptr:
     72 	.word	0x1f		/* limit (31 bytes = 4 GDT entries - 1) */
     73 	.long	BOOT_SEG + gdt_rom	/* base */
     74 
     75 	/* Some CPUs are picky about GDT alignment... */
     76 	.align	16
     77 .globl gdt_rom
     78 gdt_rom:
     79 	/*
     80 	 * The GDT table ...
     81 	 *
     82 	 *	 Selector	Type
     83 	 *	 0x00		NULL
     84 	 *	 0x08		Unused
     85 	 *	 0x10		32bit code
     86 	 *	 0x18		32bit data/stack
     87 	 */
     88 	/* The NULL Desciptor - Mandatory */
     89 	.word	0x0000		/* limit_low */
     90 	.word	0x0000		/* base_low */
     91 	.byte	0x00		/* base_middle */
     92 	.byte	0x00		/* access */
     93 	.byte	0x00		/* flags + limit_high */
     94 	.byte	0x00		/* base_high */
     95 
     96 	/* Unused Desciptor - (matches Linux) */
     97 	.word	0x0000		/* limit_low */
     98 	.word	0x0000		/* base_low */
     99 	.byte	0x00		/* base_middle */
    100 	.byte	0x00		/* access */
    101 	.byte	0x00		/* flags + limit_high */
    102 	.byte	0x00		/* base_high */
    103 
    104 	/*
    105 	 * The Code Segment Descriptor:
    106 	 * - Base   = 0x00000000
    107 	 * - Size   = 4GB
    108 	 * - Access = Present, Ring 0, Exec (Code), Readable
    109 	 * - Flags  = 4kB Granularity, 32-bit
    110 	 */
    111 	.word	0xffff		/* limit_low */
    112 	.word	0x0000		/* base_low */
    113 	.byte	0x00		/* base_middle */
    114 	.byte	0x9b		/* access */
    115 	.byte	0xcf		/* flags + limit_high */
    116 	.byte	0x00		/* base_high */
    117 
    118 	/*
    119 	 * The Data Segment Descriptor:
    120 	 * - Base   = 0x00000000
    121 	 * - Size   = 4GB
    122 	 * - Access = Present, Ring 0, Non-Exec (Data), Writable
    123 	 * - Flags  = 4kB Granularity, 32-bit
    124 	 */
    125 	.word	0xffff		/* limit_low */
    126 	.word	0x0000		/* base_low */
    127 	.byte	0x00		/* base_middle */
    128 	.byte	0x93		/* access */
    129 	.byte	0xcf		/* flags + limit_high */
    130 	.byte	0x00		/* base_high */
    131