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