1
2
3
4
5
6
7
8
9
10.text
11#include <linux/threads.h>
12#include <linux/init.h>
13#include <linux/linkage.h>
14#include <asm/segment.h>
15#include <asm/page_types.h>
16#include <asm/pgtable_types.h>
17#include <asm/cache.h>
18#include <asm/thread_info.h>
19#include <asm/asm-offsets.h>
20#include <asm/setup.h>
21#include <asm/processor-flags.h>
22#include <asm/msr-index.h>
23#include <asm/cpufeatures.h>
24#include <asm/percpu.h>
25#include <asm/nops.h>
26#include <asm/bootparam.h>
27#include <asm/export.h>
28#include <asm/pgtable_32.h>
29
30
31#define pa(X) ((X) - __PAGE_OFFSET)
32
33
34
35
36
37#define X86 new_cpu_data+CPUINFO_x86
38#define X86_VENDOR new_cpu_data+CPUINFO_x86_vendor
39#define X86_MODEL new_cpu_data+CPUINFO_x86_model
40#define X86_STEPPING new_cpu_data+CPUINFO_x86_stepping
41#define X86_HARD_MATH new_cpu_data+CPUINFO_hard_math
42#define X86_CPUID new_cpu_data+CPUINFO_cpuid_level
43#define X86_CAPABILITY new_cpu_data+CPUINFO_x86_capability
44#define X86_VENDOR_ID new_cpu_data+CPUINFO_x86_vendor_id
45
46
47#define SIZEOF_PTREGS 17*4
48
49
50
51
52
53
54KERNEL_PAGES = LOWMEM_PAGES
55
56INIT_MAP_SIZE = PAGE_TABLE_SIZE(KERNEL_PAGES) * PAGE_SIZE
57RESERVE_BRK(pagetables, INIT_MAP_SIZE)
58
59
60
61
62
63
64
65
66__HEAD
67SYM_CODE_START(startup_32)
68 movl pa(initial_stack),%ecx
69
70
71
72
73 lgdt pa(boot_gdt_descr)
74 movl $(__BOOT_DS),%eax
75 movl %eax,%ds
76 movl %eax,%es
77 movl %eax,%fs
78 movl %eax,%gs
79 movl %eax,%ss
80 leal -__PAGE_OFFSET(%ecx),%esp
81
82
83
84
85 cld
86 xorl %eax,%eax
87 movl $pa(__bss_start),%edi
88 movl $pa(__bss_stop),%ecx
89 subl %edi,%ecx
90 shrl $2,%ecx
91 rep ; stosl
92
93
94
95
96
97
98
99
100 movl $pa(boot_params),%edi
101 movl $(PARAM_SIZE/4),%ecx
102 cld
103 rep
104 movsl
105 movl pa(boot_params) + NEW_CL_POINTER,%esi
106 andl %esi,%esi
107 jz 1f
108 movl $pa(boot_command_line),%edi
109 movl $(COMMAND_LINE_SIZE/4),%ecx
110 rep
111 movsl
1121:
113
114#ifdef CONFIG_OLPC
115
116 movl %cr3, %eax
117 movl %eax, pa(olpc_ofw_pgd)
118#endif
119
120#ifdef CONFIG_MICROCODE
121
122 call load_ucode_bsp
123#endif
124
125
126 call mk_early_pgtbl_32
127
128
129 movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax
130#ifdef CONFIG_X86_PAE
131#define KPMDS (((-__PAGE_OFFSET) >> 30) & 3)
132 movl %eax,pa(initial_pg_pmd+0x1000*KPMDS-8)
133#else
134 movl %eax,pa(initial_page_table+0xffc)
135#endif
136
137 jmp .Ldefault_entry
138SYM_CODE_END(startup_32)
139
140#ifdef CONFIG_HOTPLUG_CPU
141
142
143
144
145
146SYM_FUNC_START(start_cpu0)
147 movl initial_stack, %ecx
148 movl %ecx, %esp
149 call *(initial_code)
1501: jmp 1b
151SYM_FUNC_END(start_cpu0)
152#endif
153
154
155
156
157
158
159
160
161
162SYM_FUNC_START(startup_32_smp)
163 cld
164 movl $(__BOOT_DS),%eax
165 movl %eax,%ds
166 movl %eax,%es
167 movl %eax,%fs
168 movl %eax,%gs
169 movl pa(initial_stack),%ecx
170 movl %eax,%ss
171 leal -__PAGE_OFFSET(%ecx),%esp
172
173#ifdef CONFIG_MICROCODE
174
175 call load_ucode_ap
176#endif
177
178.Ldefault_entry:
179 movl $(CR0_STATE & ~X86_CR0_PG),%eax
180 movl %eax,%cr0
181
182
183
184
185
186
187
188
189 pushl $0
190 popfl
191
192
193
194
195
196
197
198 movl $-1,pa(X86_CPUID)
199 movl $X86_EFLAGS_ID,%ecx
200 pushl %ecx
201 popfl
202 pushfl
203 popl %eax
204 testl $X86_EFLAGS_ID,%eax
205 jz .Lenable_paging
206
207
208 xorl %eax,%eax
209 cpuid
210 movl %eax,pa(X86_CPUID)
211
212 movl $1,%eax
213 cpuid
214 andl $~1,%edx
215 jz .Lenable_paging
216
217 movl pa(mmu_cr4_features),%eax
218 movl %eax,%cr4
219
220 testb $X86_CR4_PAE, %al
221 jz .Lenable_paging
222
223
224 movl $0x80000000, %eax
225 cpuid
226
227 subl $0x80000001, %eax
228 cmpl $(0x8000ffff-0x80000001), %eax
229 ja .Lenable_paging
230
231
232 call verify_cpu
233
234 mov $0x80000001, %eax
235 cpuid
236
237 btl $(X86_FEATURE_NX & 31), %edx
238 jnc .Lenable_paging
239
240
241 movl $MSR_EFER, %ecx
242 rdmsr
243
244 btsl $_EFER_NX, %eax
245
246 wrmsr
247
248.Lenable_paging:
249
250
251
252
253 movl $pa(initial_page_table), %eax
254 movl %eax,%cr3
255 movl $CR0_STATE,%eax
256 movl %eax,%cr0
257 ljmp $__BOOT_CS,$1f
2581:
259
260 addl $__PAGE_OFFSET, %esp
261
262
263
264
265
266 movl setup_once_ref,%eax
267 andl %eax,%eax
268 jz 1f
269 call *%eax
2701:
271
272
273
274
275 movb $4,X86
276 cmpl $-1,X86_CPUID
277 je .Lis486
278
279
280 xorl %eax,%eax
281 cpuid
282 movl %eax,X86_CPUID
283 movl %ebx,X86_VENDOR_ID
284 movl %edx,X86_VENDOR_ID+4
285 movl %ecx,X86_VENDOR_ID+8
286
287 orl %eax,%eax
288 je .Lis486
289
290 movl $1,%eax
291 cpuid
292 movb %al,%cl
293 andb $0x0f,%ah
294 movb %ah,X86
295 andb $0xf0,%al
296 shrb $4,%al
297 movb %al,X86_MODEL
298 andb $0x0f,%cl
299 movb %cl,X86_STEPPING
300 movl %edx,X86_CAPABILITY
301
302.Lis486:
303 movl $0x50022,%ecx
304 movl %cr0,%eax
305 andl $0x80000011,%eax
306 orl %ecx,%eax
307 movl %eax,%cr0
308
309 lgdt early_gdt_descr
310 ljmp $(__KERNEL_CS),$1f
3111: movl $(__KERNEL_DS),%eax
312 movl %eax,%ss
313
314 movl $(__USER_DS),%eax
315 movl %eax,%ds
316 movl %eax,%es
317
318 movl $(__KERNEL_PERCPU), %eax
319 movl %eax,%fs
320
321 movl $(__KERNEL_STACK_CANARY),%eax
322 movl %eax,%gs
323
324 xorl %eax,%eax
325 lldt %ax
326
327 call *(initial_code)
3281: jmp 1b
329SYM_FUNC_END(startup_32_smp)
330
331#include "verify_cpu.S"
332
333
334
335
336
337
338
339
340__INIT
341setup_once:
342#ifdef CONFIG_STACKPROTECTOR
343
344
345
346
347
348 movl $gdt_page,%eax
349 movl $stack_canary,%ecx
350 movw %cx, 8 * GDT_ENTRY_STACK_CANARY + 2(%eax)
351 shrl $16, %ecx
352 movb %cl, 8 * GDT_ENTRY_STACK_CANARY + 4(%eax)
353 movb %ch, 8 * GDT_ENTRY_STACK_CANARY + 7(%eax)
354#endif
355
356 andl $0,setup_once_ref
357 ret
358
359SYM_FUNC_START(early_idt_handler_array)
360
361
362
363
364 i = 0
365 .rept NUM_EXCEPTION_VECTORS
366 .if ((EXCEPTION_ERRCODE_MASK >> i) & 1) == 0
367 pushl $0
368 .endif
369 pushl $i
370 jmp early_idt_handler_common
371 i = i + 1
372 .fill early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE - ., 1, 0xcc
373 .endr
374SYM_FUNC_END(early_idt_handler_array)
375
376SYM_CODE_START_LOCAL(early_idt_handler_common)
377
378
379
380
381 cld
382
383 incl %ss:early_recursion_flag
384
385
386
387 cld
388 pushl %fs
389 pushl %es
390 pushl %ds
391 pushl %eax
392 pushl %ebp
393 pushl %edi
394 pushl %esi
395 pushl %edx
396 pushl %ecx
397 pushl %ebx
398
399
400 movl $(__KERNEL_DS), %ecx
401 movl %ecx, %ds
402 movl %ecx, %es
403
404
405 movl PT_GS(%esp), %edx
406
407
408 movw %gs, PT_GS(%esp)
409
410 movl %esp, %eax
411 call early_fixup_exception
412
413 popl %ebx
414 popl %ecx
415 popl %edx
416 popl %esi
417 popl %edi
418 popl %ebp
419 popl %eax
420 popl %ds
421 popl %es
422 popl %fs
423 popl %gs
424 decl %ss:early_recursion_flag
425 addl $4, %esp
426 iret
427SYM_CODE_END(early_idt_handler_common)
428
429
430SYM_FUNC_START(early_ignore_irq)
431 cld
432#ifdef CONFIG_PRINTK
433 pushl %eax
434 pushl %ecx
435 pushl %edx
436 pushl %es
437 pushl %ds
438 movl $(__KERNEL_DS),%eax
439 movl %eax,%ds
440 movl %eax,%es
441 cmpl $2,early_recursion_flag
442 je hlt_loop
443 incl early_recursion_flag
444 pushl 16(%esp)
445 pushl 24(%esp)
446 pushl 32(%esp)
447 pushl 40(%esp)
448 pushl $int_msg
449 call printk
450
451 call dump_stack
452
453 addl $(5*4),%esp
454 popl %ds
455 popl %es
456 popl %edx
457 popl %ecx
458 popl %eax
459#endif
460 iret
461
462hlt_loop:
463 hlt
464 jmp hlt_loop
465SYM_FUNC_END(early_ignore_irq)
466
467__INITDATA
468 .align 4
469SYM_DATA(early_recursion_flag, .long 0)
470
471__REFDATA
472 .align 4
473SYM_DATA(initial_code, .long i386_start_kernel)
474SYM_DATA(setup_once_ref, .long setup_once)
475
476#ifdef CONFIG_PAGE_TABLE_ISOLATION
477#define PGD_ALIGN (2 * PAGE_SIZE)
478#define PTI_USER_PGD_FILL 1024
479#else
480#define PGD_ALIGN (PAGE_SIZE)
481#define PTI_USER_PGD_FILL 0
482#endif
483
484
485
486__PAGE_ALIGNED_BSS
487 .align PGD_ALIGN
488#ifdef CONFIG_X86_PAE
489.globl initial_pg_pmd
490initial_pg_pmd:
491 .fill 1024*KPMDS,4,0
492#else
493.globl initial_page_table
494initial_page_table:
495 .fill 1024,4,0
496#endif
497 .align PGD_ALIGN
498initial_pg_fixmap:
499 .fill 1024,4,0
500.globl swapper_pg_dir
501 .align PGD_ALIGN
502swapper_pg_dir:
503 .fill 1024,4,0
504 .fill PTI_USER_PGD_FILL,4,0
505.globl empty_zero_page
506empty_zero_page:
507 .fill 4096,1,0
508EXPORT_SYMBOL(empty_zero_page)
509
510
511
512
513#ifdef CONFIG_X86_PAE
514__PAGE_ALIGNED_DATA
515
516 .align PGD_ALIGN
517SYM_DATA_START(initial_page_table)
518 .long pa(initial_pg_pmd+PGD_IDENT_ATTR),0
519
520 .long pa(initial_pg_pmd+PGD_IDENT_ATTR),0
521 .long pa(initial_pg_pmd+PGD_IDENT_ATTR+0x1000),0
522 .long pa(initial_pg_pmd+PGD_IDENT_ATTR+0x2000),0
523
524 .long 0,0
525 .long pa(initial_pg_pmd+PGD_IDENT_ATTR),0
526 .long pa(initial_pg_pmd+PGD_IDENT_ATTR+0x1000),0
527
528 .long 0,0
529 .long 0,0
530 .long pa(initial_pg_pmd+PGD_IDENT_ATTR),0
531# else
532
533# endif
534 .align PAGE_SIZE
535
536#ifdef CONFIG_PAGE_TABLE_ISOLATION
537
538
539
540
541
542 .fill 1024, 4, 0
543#endif
544
545SYM_DATA_END(initial_page_table)
546#endif
547
548.data
549.balign 4
550
551
552
553
554SYM_DATA(initial_stack,
555 .long init_thread_union + THREAD_SIZE -
556 SIZEOF_PTREGS - TOP_OF_KERNEL_STACK_PADDING)
557
558__INITRODATA
559int_msg:
560 .asciz "Unknown interrupt or fault at: %p %p %p\n"
561
562#include "../../x86/xen/xen-head.S"
563
564
565
566
567
568
569
570
571 .data
572 ALIGN
573
574 .word 0
575SYM_DATA_START_LOCAL(boot_gdt_descr)
576 .word __BOOT_DS+7
577 .long boot_gdt - __PAGE_OFFSET
578SYM_DATA_END(boot_gdt_descr)
579
580
581 .word 0
582SYM_DATA_START(early_gdt_descr)
583 .word GDT_ENTRIES*8-1
584 .long gdt_page
585SYM_DATA_END(early_gdt_descr)
586
587
588
589
590
591 .align L1_CACHE_BYTES
592SYM_DATA_START(boot_gdt)
593 .fill GDT_ENTRY_BOOT_CS,8,0
594 .quad 0x00cf9a000000ffff
595 .quad 0x00cf92000000ffff
596SYM_DATA_END(boot_gdt)
597