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#include <common.h>
37#include <command.h>
38#include <asm/interrupt.h>
39
40
41
42#define GDT_ENTRY(flags, base, limit) \
43 ((((base) & 0xff000000ULL) << (56-24)) | \
44 (((flags) & 0x0000f0ffULL) << 40) | \
45 (((limit) & 0x000f0000ULL) << (48-16)) | \
46 (((base) & 0x00ffffffULL) << 16) | \
47 (((limit) & 0x0000ffffULL)))
48
49
50
51#define GDT_ENTRY_32BIT_CS 2
52#define GDT_ENTRY_32BIT_DS (GDT_ENTRY_32BIT_CS + 1)
53#define GDT_ENTRY_16BIT_CS (GDT_ENTRY_32BIT_DS + 1)
54#define GDT_ENTRY_16BIT_DS (GDT_ENTRY_16BIT_CS + 1)
55
56
57
58
59
60struct gdt_ptr {
61 u16 len;
62 u32 ptr;
63} __attribute__((packed));
64
65static void reload_gdt(void)
66{
67
68
69 static const u64 boot_gdt[] __attribute__((aligned(16))) = {
70
71 [GDT_ENTRY_32BIT_CS] = GDT_ENTRY(0xc09b, 0, 0xfffff),
72
73 [GDT_ENTRY_32BIT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff),
74
75 [GDT_ENTRY_16BIT_CS] = GDT_ENTRY(0x109b, 0, 0x0ffff),
76
77 [GDT_ENTRY_16BIT_DS] = GDT_ENTRY(0x1093, 0, 0x0ffff),
78 };
79 static struct gdt_ptr gdt;
80
81 gdt.len = sizeof(boot_gdt)-1;
82 gdt.ptr = (u32)&boot_gdt;
83
84 asm volatile("lgdtl %0\n" \
85 "movl $((2+1)*8), %%ecx\n" \
86 "movl %%ecx, %%ds\n" \
87 "movl %%ecx, %%es\n" \
88 "movl %%ecx, %%fs\n" \
89 "movl %%ecx, %%gs\n" \
90 "movl %%ecx, %%ss" \
91 : : "m" (gdt) : "ecx");
92}
93
94
95int cpu_init_f(void)
96{
97
98 asm ("fninit\n" \
99 "movl %cr0, %eax\n" \
100 "andl $~0x4, %eax\n" \
101 "orl $0x22, %eax\n" \
102 "movl %eax, %cr0\n" );
103
104 return 0;
105}
106
107int cpu_init_r(void)
108{
109 reload_gdt();
110
111
112 cpu_init_interrupts ();
113 return 0;
114}
115
116int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
117{
118 printf ("resetting ...\n");
119 udelay(50000);
120 disable_interrupts();
121 reset_cpu(0);
122
123
124 return 0;
125}
126
127void flush_cache (unsigned long dummy1, unsigned long dummy2)
128{
129 asm("wbinvd\n");
130 return;
131}
132
133void __attribute__ ((regparm(0))) generate_gpf(void);
134
135
136asm(".globl generate_gpf\n"
137 ".hidden generate_gpf\n"
138 ".type generate_gpf, @function\n"
139 "generate_gpf:\n"
140 "ljmp $0x70, $0x47114711\n");
141
142void __reset_cpu(ulong addr)
143{
144 printf("Resetting using i386 Triple Fault\n");
145 set_vector(13, generate_gpf);
146 set_vector(8, generate_gpf);
147 generate_gpf();
148}
149void reset_cpu(ulong addr) __attribute__((weak, alias("__reset_cpu")));
150