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 xorl %eax,%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 andl $0,setup_once_ref
343 ret
344
345SYM_FUNC_START(early_idt_handler_array)
346
347
348
349
350 i = 0
351 .rept NUM_EXCEPTION_VECTORS
352 .if ((EXCEPTION_ERRCODE_MASK >> i) & 1) == 0
353 pushl $0
354 .endif
355 pushl $i
356 jmp early_idt_handler_common
357 i = i + 1
358 .fill early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE - ., 1, 0xcc
359 .endr
360SYM_FUNC_END(early_idt_handler_array)
361
362SYM_CODE_START_LOCAL(early_idt_handler_common)
363
364
365
366
367 cld
368
369 incl %ss:early_recursion_flag
370
371
372
373 cld
374 pushl %fs
375 pushl %es
376 pushl %ds
377 pushl %eax
378 pushl %ebp
379 pushl %edi
380 pushl %esi
381 pushl %edx
382 pushl %ecx
383 pushl %ebx
384
385
386 movl $(__KERNEL_DS), %ecx
387 movl %ecx, %ds
388 movl %ecx, %es
389
390
391 movl PT_GS(%esp), %edx
392
393
394 movw %gs, PT_GS(%esp)
395
396 movl %esp, %eax
397 call early_fixup_exception
398
399 popl %ebx
400 popl %ecx
401 popl %edx
402 popl %esi
403 popl %edi
404 popl %ebp
405 popl %eax
406 popl %ds
407 popl %es
408 popl %fs
409 popl %gs
410 decl %ss:early_recursion_flag
411 addl $4, %esp
412 iret
413SYM_CODE_END(early_idt_handler_common)
414
415
416SYM_FUNC_START(early_ignore_irq)
417 cld
418#ifdef CONFIG_PRINTK
419 pushl %eax
420 pushl %ecx
421 pushl %edx
422 pushl %es
423 pushl %ds
424 movl $(__KERNEL_DS),%eax
425 movl %eax,%ds
426 movl %eax,%es
427 cmpl $2,early_recursion_flag
428 je hlt_loop
429 incl early_recursion_flag
430 pushl 16(%esp)
431 pushl 24(%esp)
432 pushl 32(%esp)
433 pushl 40(%esp)
434 pushl $int_msg
435 call _printk
436
437 call dump_stack
438
439 addl $(5*4),%esp
440 popl %ds
441 popl %es
442 popl %edx
443 popl %ecx
444 popl %eax
445#endif
446 iret
447
448hlt_loop:
449 hlt
450 jmp hlt_loop
451SYM_FUNC_END(early_ignore_irq)
452
453__INITDATA
454 .align 4
455SYM_DATA(early_recursion_flag, .long 0)
456
457__REFDATA
458 .align 4
459SYM_DATA(initial_code, .long i386_start_kernel)
460SYM_DATA(setup_once_ref, .long setup_once)
461
462#ifdef CONFIG_PAGE_TABLE_ISOLATION
463#define PGD_ALIGN (2 * PAGE_SIZE)
464#define PTI_USER_PGD_FILL 1024
465#else
466#define PGD_ALIGN (PAGE_SIZE)
467#define PTI_USER_PGD_FILL 0
468#endif
469
470
471
472__PAGE_ALIGNED_BSS
473 .align PGD_ALIGN
474#ifdef CONFIG_X86_PAE
475.globl initial_pg_pmd
476initial_pg_pmd:
477 .fill 1024*KPMDS,4,0
478#else
479.globl initial_page_table
480initial_page_table:
481 .fill 1024,4,0
482#endif
483 .align PGD_ALIGN
484initial_pg_fixmap:
485 .fill 1024,4,0
486.globl swapper_pg_dir
487 .align PGD_ALIGN
488swapper_pg_dir:
489 .fill 1024,4,0
490 .fill PTI_USER_PGD_FILL,4,0
491.globl empty_zero_page
492empty_zero_page:
493 .fill 4096,1,0
494EXPORT_SYMBOL(empty_zero_page)
495
496
497
498
499#ifdef CONFIG_X86_PAE
500__PAGE_ALIGNED_DATA
501
502 .align PGD_ALIGN
503SYM_DATA_START(initial_page_table)
504 .long pa(initial_pg_pmd+PGD_IDENT_ATTR),0
505
506 .long pa(initial_pg_pmd+PGD_IDENT_ATTR),0
507 .long pa(initial_pg_pmd+PGD_IDENT_ATTR+0x1000),0
508 .long pa(initial_pg_pmd+PGD_IDENT_ATTR+0x2000),0
509
510 .long 0,0
511 .long pa(initial_pg_pmd+PGD_IDENT_ATTR),0
512 .long pa(initial_pg_pmd+PGD_IDENT_ATTR+0x1000),0
513
514 .long 0,0
515 .long 0,0
516 .long pa(initial_pg_pmd+PGD_IDENT_ATTR),0
517# else
518
519# endif
520 .align PAGE_SIZE
521
522#ifdef CONFIG_PAGE_TABLE_ISOLATION
523
524
525
526
527
528 .fill 1024, 4, 0
529#endif
530
531SYM_DATA_END(initial_page_table)
532#endif
533
534.data
535.balign 4
536
537
538
539
540SYM_DATA(initial_stack,
541 .long init_thread_union + THREAD_SIZE -
542 SIZEOF_PTREGS - TOP_OF_KERNEL_STACK_PADDING)
543
544__INITRODATA
545int_msg:
546 .asciz "Unknown interrupt or fault at: %p %p %p\n"
547
548#include "../../x86/xen/xen-head.S"
549
550
551
552
553
554
555
556
557 .data
558 ALIGN
559
560 .word 0
561SYM_DATA_START_LOCAL(boot_gdt_descr)
562 .word __BOOT_DS+7
563 .long boot_gdt - __PAGE_OFFSET
564SYM_DATA_END(boot_gdt_descr)
565
566
567 .word 0
568SYM_DATA_START(early_gdt_descr)
569 .word GDT_ENTRIES*8-1
570 .long gdt_page
571SYM_DATA_END(early_gdt_descr)
572
573
574
575
576
577 .align L1_CACHE_BYTES
578SYM_DATA_START(boot_gdt)
579 .fill GDT_ENTRY_BOOT_CS,8,0
580 .quad 0x00cf9a000000ffff
581 .quad 0x00cf92000000ffff
582SYM_DATA_END(boot_gdt)
583