linux/arch/x86/kernel/head_32.S
<<
>>
Prefs
   1/*
   2 *
   3 *  Copyright (C) 1991, 1992  Linus Torvalds
   4 *
   5 *  Enhanced CPU detection and feature setting code by Mike Jagdis
   6 *  and Martin Mares, November 1997.
   7 */
   8
   9.text
  10#include <linux/threads.h>
  11#include <linux/init.h>
  12#include <linux/linkage.h>
  13#include <asm/segment.h>
  14#include <asm/page.h>
  15#include <asm/pgtable.h>
  16#include <asm/desc.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
  23/* Physical address */
  24#define pa(X) ((X) - __PAGE_OFFSET)
  25
  26/*
  27 * References to members of the new_cpu_data structure.
  28 */
  29
  30#define X86             new_cpu_data+CPUINFO_x86
  31#define X86_VENDOR      new_cpu_data+CPUINFO_x86_vendor
  32#define X86_MODEL       new_cpu_data+CPUINFO_x86_model
  33#define X86_MASK        new_cpu_data+CPUINFO_x86_mask
  34#define X86_HARD_MATH   new_cpu_data+CPUINFO_hard_math
  35#define X86_CPUID       new_cpu_data+CPUINFO_cpuid_level
  36#define X86_CAPABILITY  new_cpu_data+CPUINFO_x86_capability
  37#define X86_VENDOR_ID   new_cpu_data+CPUINFO_x86_vendor_id
  38
  39/*
  40 * This is how much memory *in addition to the memory covered up to
  41 * and including _end* we need mapped initially.
  42 * We need:
  43 *  - one bit for each possible page, but only in low memory, which means
  44 *     2^32/4096/8 = 128K worst case (4G/4G split.)
  45 *  - enough space to map all low memory, which means
  46 *     (2^32/4096) / 1024 pages (worst case, non PAE)
  47 *     (2^32/4096) / 512 + 4 pages (worst case for PAE)
  48 *  - a few pages for allocator use before the kernel pagetable has
  49 *     been set up
  50 *
  51 * Modulo rounding, each megabyte assigned here requires a kilobyte of
  52 * memory, which is currently unreclaimed.
  53 *
  54 * This should be a multiple of a page.
  55 */
  56LOW_PAGES = 1<<(32-PAGE_SHIFT_asm)
  57
  58/*
  59 * To preserve the DMA pool in PAGEALLOC kernels, we'll allocate
  60 * pagetables from above the 16MB DMA limit, so we'll have to set
  61 * up pagetables 16MB more (worst-case):
  62 */
  63#ifdef CONFIG_DEBUG_PAGEALLOC
  64LOW_PAGES = LOW_PAGES + 0x1000000
  65#endif
  66
  67#if PTRS_PER_PMD > 1
  68PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD
  69#else
  70PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD)
  71#endif
  72BOOTBITMAP_SIZE = LOW_PAGES / 8
  73ALLOCATOR_SLOP = 4
  74
  75INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm
  76
  77/*
  78 * 32-bit kernel entrypoint; only used by the boot CPU.  On entry,
  79 * %esi points to the real-mode code as a 32-bit pointer.
  80 * CS and DS must be 4 GB flat segments, but we don't depend on
  81 * any particular GDT layout, because we load our own as soon as we
  82 * can.
  83 */
  84.section .text.head,"ax",@progbits
  85ENTRY(startup_32)
  86        /* test KEEP_SEGMENTS flag to see if the bootloader is asking
  87                us to not reload segments */
  88        testb $(1<<6), BP_loadflags(%esi)
  89        jnz 2f
  90
  91/*
  92 * Set segments to known values.
  93 */
  94        lgdt pa(boot_gdt_descr)
  95        movl $(__BOOT_DS),%eax
  96        movl %eax,%ds
  97        movl %eax,%es
  98        movl %eax,%fs
  99        movl %eax,%gs
 1002:
 101
 102/*
 103 * Clear BSS first so that there are no surprises...
 104 */
 105        cld
 106        xorl %eax,%eax
 107        movl $pa(__bss_start),%edi
 108        movl $pa(__bss_stop),%ecx
 109        subl %edi,%ecx
 110        shrl $2,%ecx
 111        rep ; stosl
 112/*
 113 * Copy bootup parameters out of the way.
 114 * Note: %esi still has the pointer to the real-mode data.
 115 * With the kexec as boot loader, parameter segment might be loaded beyond
 116 * kernel image and might not even be addressable by early boot page tables.
 117 * (kexec on panic case). Hence copy out the parameters before initializing
 118 * page tables.
 119 */
 120        movl $pa(boot_params),%edi
 121        movl $(PARAM_SIZE/4),%ecx
 122        cld
 123        rep
 124        movsl
 125        movl pa(boot_params) + NEW_CL_POINTER,%esi
 126        andl %esi,%esi
 127        jz 1f                   # No comand line
 128        movl $pa(boot_command_line),%edi
 129        movl $(COMMAND_LINE_SIZE/4),%ecx
 130        rep
 131        movsl
 1321:
 133
 134#ifdef CONFIG_PARAVIRT
 135        /* This is can only trip for a broken bootloader... */
 136        cmpw $0x207, pa(boot_params + BP_version)
 137        jb default_entry
 138
 139        /* Paravirt-compatible boot parameters.  Look to see what architecture
 140                we're booting under. */
 141        movl pa(boot_params + BP_hardware_subarch), %eax
 142        cmpl $num_subarch_entries, %eax
 143        jae bad_subarch
 144
 145        movl pa(subarch_entries)(,%eax,4), %eax
 146        subl $__PAGE_OFFSET, %eax
 147        jmp *%eax
 148
 149bad_subarch:
 150WEAK(lguest_entry)
 151WEAK(xen_entry)
 152        /* Unknown implementation; there's really
 153           nothing we can do at this point. */
 154        ud2a
 155
 156        __INITDATA
 157
 158subarch_entries:
 159        .long default_entry             /* normal x86/PC */
 160        .long lguest_entry              /* lguest hypervisor */
 161        .long xen_entry                 /* Xen hypervisor */
 162num_subarch_entries = (. - subarch_entries) / 4
 163.previous
 164#endif /* CONFIG_PARAVIRT */
 165
 166/*
 167 * Initialize page tables.  This creates a PDE and a set of page
 168 * tables, which are located immediately beyond _end.  The variable
 169 * init_pg_tables_end is set up to point to the first "safe" location.
 170 * Mappings are created both at virtual address 0 (identity mapping)
 171 * and PAGE_OFFSET for up to _end+sizeof(page tables)+INIT_MAP_BEYOND_END.
 172 *
 173 * Note that the stack is not yet set up!
 174 */
 175default_entry:
 176#ifdef CONFIG_X86_PAE
 177
 178        /*
 179         * In PAE mode swapper_pg_dir is statically defined to contain enough
 180         * entries to cover the VMSPLIT option (that is the top 1, 2 or 3
 181         * entries). The identity mapping is handled by pointing two PGD
 182         * entries to the first kernel PMD.
 183         *
 184         * Note the upper half of each PMD or PTE are always zero at
 185         * this stage.
 186         */
 187
 188#define KPMDS (((-__PAGE_OFFSET) >> 30) & 3) /* Number of kernel PMDs */
 189
 190        xorl %ebx,%ebx                          /* %ebx is kept at zero */
 191
 192        movl $pa(pg0), %edi
 193        movl %edi, pa(init_pg_tables_start)
 194        movl $pa(swapper_pg_pmd), %edx
 195        movl $PTE_IDENT_ATTR, %eax
 19610:
 197        leal PDE_IDENT_ATTR(%edi),%ecx          /* Create PMD entry */
 198        movl %ecx,(%edx)                        /* Store PMD entry */
 199                                                /* Upper half already zero */
 200        addl $8,%edx
 201        movl $512,%ecx
 20211:
 203        stosl
 204        xchgl %eax,%ebx
 205        stosl
 206        xchgl %eax,%ebx
 207        addl $0x1000,%eax
 208        loop 11b
 209
 210        /*
 211         * End condition: we must map up to and including INIT_MAP_BEYOND_END
 212         * bytes beyond the end of our own page tables.
 213         */
 214        leal (INIT_MAP_BEYOND_END+PTE_IDENT_ATTR)(%edi),%ebp
 215        cmpl %ebp,%eax
 216        jb 10b
 2171:
 218        movl %edi,pa(init_pg_tables_end)
 219        shrl $12, %eax
 220        movl %eax, pa(max_pfn_mapped)
 221
 222        /* Do early initialization of the fixmap area */
 223        movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,%eax
 224        movl %eax,pa(swapper_pg_pmd+0x1000*KPMDS-8)
 225#else   /* Not PAE */
 226
 227page_pde_offset = (__PAGE_OFFSET >> 20);
 228
 229        movl $pa(pg0), %edi
 230        movl %edi, pa(init_pg_tables_start)
 231        movl $pa(swapper_pg_dir), %edx
 232        movl $PTE_IDENT_ATTR, %eax
 23310:
 234        leal PDE_IDENT_ATTR(%edi),%ecx          /* Create PDE entry */
 235        movl %ecx,(%edx)                        /* Store identity PDE entry */
 236        movl %ecx,page_pde_offset(%edx)         /* Store kernel PDE entry */
 237        addl $4,%edx
 238        movl $1024, %ecx
 23911:
 240        stosl
 241        addl $0x1000,%eax
 242        loop 11b
 243        /*
 244         * End condition: we must map up to and including INIT_MAP_BEYOND_END
 245         * bytes beyond the end of our own page tables; the +0x007 is
 246         * the attribute bits
 247         */
 248        leal (INIT_MAP_BEYOND_END+PTE_IDENT_ATTR)(%edi),%ebp
 249        cmpl %ebp,%eax
 250        jb 10b
 251        movl %edi,pa(init_pg_tables_end)
 252        shrl $12, %eax
 253        movl %eax, pa(max_pfn_mapped)
 254
 255        /* Do early initialization of the fixmap area */
 256        movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,%eax
 257        movl %eax,pa(swapper_pg_dir+0xffc)
 258#endif
 259        jmp 3f
 260/*
 261 * Non-boot CPU entry point; entered from trampoline.S
 262 * We can't lgdt here, because lgdt itself uses a data segment, but
 263 * we know the trampoline has already loaded the boot_gdt for us.
 264 *
 265 * If cpu hotplug is not supported then this code can go in init section
 266 * which will be freed later
 267 */
 268
 269#ifndef CONFIG_HOTPLUG_CPU
 270.section .init.text,"ax",@progbits
 271#endif
 272
 273#ifdef CONFIG_SMP
 274ENTRY(startup_32_smp)
 275        cld
 276        movl $(__BOOT_DS),%eax
 277        movl %eax,%ds
 278        movl %eax,%es
 279        movl %eax,%fs
 280        movl %eax,%gs
 281#endif /* CONFIG_SMP */
 2823:
 283
 284/*
 285 *      New page tables may be in 4Mbyte page mode and may
 286 *      be using the global pages. 
 287 *
 288 *      NOTE! If we are on a 486 we may have no cr4 at all!
 289 *      So we do not try to touch it unless we really have
 290 *      some bits in it to set.  This won't work if the BSP
 291 *      implements cr4 but this AP does not -- very unlikely
 292 *      but be warned!  The same applies to the pse feature
 293 *      if not equally supported. --macro
 294 *
 295 *      NOTE! We have to correct for the fact that we're
 296 *      not yet offset PAGE_OFFSET..
 297 */
 298#define cr4_bits pa(mmu_cr4_features)
 299        movl cr4_bits,%edx
 300        andl %edx,%edx
 301        jz 6f
 302        movl %cr4,%eax          # Turn on paging options (PSE,PAE,..)
 303        orl %edx,%eax
 304        movl %eax,%cr4
 305
 306        btl $5, %eax            # check if PAE is enabled
 307        jnc 6f
 308
 309        /* Check if extended functions are implemented */
 310        movl $0x80000000, %eax
 311        cpuid
 312        cmpl $0x80000000, %eax
 313        jbe 6f
 314        mov $0x80000001, %eax
 315        cpuid
 316        /* Execute Disable bit supported? */
 317        btl $20, %edx
 318        jnc 6f
 319
 320        /* Setup EFER (Extended Feature Enable Register) */
 321        movl $0xc0000080, %ecx
 322        rdmsr
 323
 324        btsl $11, %eax
 325        /* Make changes effective */
 326        wrmsr
 327
 3286:
 329
 330/*
 331 * Enable paging
 332 */
 333        movl $pa(swapper_pg_dir),%eax
 334        movl %eax,%cr3          /* set the page table pointer.. */
 335        movl %cr0,%eax
 336        orl  $X86_CR0_PG,%eax
 337        movl %eax,%cr0          /* ..and set paging (PG) bit */
 338        ljmp $__BOOT_CS,$1f     /* Clear prefetch and normalize %eip */
 3391:
 340        /* Set up the stack pointer */
 341        lss stack_start,%esp
 342
 343/*
 344 * Initialize eflags.  Some BIOS's leave bits like NT set.  This would
 345 * confuse the debugger if this code is traced.
 346 * XXX - best to initialize before switching to protected mode.
 347 */
 348        pushl $0
 349        popfl
 350
 351#ifdef CONFIG_SMP
 352        cmpb $0, ready
 353        jz  1f                          /* Initial CPU cleans BSS */
 354        jmp checkCPUtype
 3551:
 356#endif /* CONFIG_SMP */
 357
 358/*
 359 * start system 32-bit setup. We need to re-do some of the things done
 360 * in 16-bit mode for the "real" operations.
 361 */
 362        call setup_idt
 363
 364checkCPUtype:
 365
 366        movl $-1,X86_CPUID              #  -1 for no CPUID initially
 367
 368/* check if it is 486 or 386. */
 369/*
 370 * XXX - this does a lot of unnecessary setup.  Alignment checks don't
 371 * apply at our cpl of 0 and the stack ought to be aligned already, and
 372 * we don't need to preserve eflags.
 373 */
 374
 375        movb $3,X86             # at least 386
 376        pushfl                  # push EFLAGS
 377        popl %eax               # get EFLAGS
 378        movl %eax,%ecx          # save original EFLAGS
 379        xorl $0x240000,%eax     # flip AC and ID bits in EFLAGS
 380        pushl %eax              # copy to EFLAGS
 381        popfl                   # set EFLAGS
 382        pushfl                  # get new EFLAGS
 383        popl %eax               # put it in eax
 384        xorl %ecx,%eax          # change in flags
 385        pushl %ecx              # restore original EFLAGS
 386        popfl
 387        testl $0x40000,%eax     # check if AC bit changed
 388        je is386
 389
 390        movb $4,X86             # at least 486
 391        testl $0x200000,%eax    # check if ID bit changed
 392        je is486
 393
 394        /* get vendor info */
 395        xorl %eax,%eax                  # call CPUID with 0 -> return vendor ID
 396        cpuid
 397        movl %eax,X86_CPUID             # save CPUID level
 398        movl %ebx,X86_VENDOR_ID         # lo 4 chars
 399        movl %edx,X86_VENDOR_ID+4       # next 4 chars
 400        movl %ecx,X86_VENDOR_ID+8       # last 4 chars
 401
 402        orl %eax,%eax                   # do we have processor info as well?
 403        je is486
 404
 405        movl $1,%eax            # Use the CPUID instruction to get CPU type
 406        cpuid
 407        movb %al,%cl            # save reg for future use
 408        andb $0x0f,%ah          # mask processor family
 409        movb %ah,X86
 410        andb $0xf0,%al          # mask model
 411        shrb $4,%al
 412        movb %al,X86_MODEL
 413        andb $0x0f,%cl          # mask mask revision
 414        movb %cl,X86_MASK
 415        movl %edx,X86_CAPABILITY
 416
 417is486:  movl $0x50022,%ecx      # set AM, WP, NE and MP
 418        jmp 2f
 419
 420is386:  movl $2,%ecx            # set MP
 4212:      movl %cr0,%eax
 422        andl $0x80000011,%eax   # Save PG,PE,ET
 423        orl %ecx,%eax
 424        movl %eax,%cr0
 425
 426        call check_x87
 427        lgdt early_gdt_descr
 428        lidt idt_descr
 429        ljmp $(__KERNEL_CS),$1f
 4301:      movl $(__KERNEL_DS),%eax        # reload all the segment registers
 431        movl %eax,%ss                   # after changing gdt.
 432        movl %eax,%fs                   # gets reset once there's real percpu
 433
 434        movl $(__USER_DS),%eax          # DS/ES contains default USER segment
 435        movl %eax,%ds
 436        movl %eax,%es
 437
 438        xorl %eax,%eax                  # Clear GS and LDT
 439        movl %eax,%gs
 440        lldt %ax
 441
 442        cld                     # gcc2 wants the direction flag cleared at all times
 443        pushl $0                # fake return address for unwinder
 444#ifdef CONFIG_SMP
 445        movb ready, %cl
 446        movb $1, ready
 447        cmpb $0,%cl             # the first CPU calls start_kernel
 448        je   1f
 449        movl $(__KERNEL_PERCPU), %eax
 450        movl %eax,%fs           # set this cpu's percpu
 451        movl (stack_start), %esp
 4521:
 453#endif /* CONFIG_SMP */
 454        jmp *(initial_code)
 455
 456/*
 457 * We depend on ET to be correct. This checks for 287/387.
 458 */
 459check_x87:
 460        movb $0,X86_HARD_MATH
 461        clts
 462        fninit
 463        fstsw %ax
 464        cmpb $0,%al
 465        je 1f
 466        movl %cr0,%eax          /* no coprocessor: have to set bits */
 467        xorl $4,%eax            /* set EM */
 468        movl %eax,%cr0
 469        ret
 470        ALIGN
 4711:      movb $1,X86_HARD_MATH
 472        .byte 0xDB,0xE4         /* fsetpm for 287, ignored by 387 */
 473        ret
 474
 475/*
 476 *  setup_idt
 477 *
 478 *  sets up a idt with 256 entries pointing to
 479 *  ignore_int, interrupt gates. It doesn't actually load
 480 *  idt - that can be done only after paging has been enabled
 481 *  and the kernel moved to PAGE_OFFSET. Interrupts
 482 *  are enabled elsewhere, when we can be relatively
 483 *  sure everything is ok.
 484 *
 485 *  Warning: %esi is live across this function.
 486 */
 487setup_idt:
 488        lea ignore_int,%edx
 489        movl $(__KERNEL_CS << 16),%eax
 490        movw %dx,%ax            /* selector = 0x0010 = cs */
 491        movw $0x8E00,%dx        /* interrupt gate - dpl=0, present */
 492
 493        lea idt_table,%edi
 494        mov $256,%ecx
 495rp_sidt:
 496        movl %eax,(%edi)
 497        movl %edx,4(%edi)
 498        addl $8,%edi
 499        dec %ecx
 500        jne rp_sidt
 501
 502.macro  set_early_handler handler,trapno
 503        lea \handler,%edx
 504        movl $(__KERNEL_CS << 16),%eax
 505        movw %dx,%ax
 506        movw $0x8E00,%dx        /* interrupt gate - dpl=0, present */
 507        lea idt_table,%edi
 508        movl %eax,8*\trapno(%edi)
 509        movl %edx,8*\trapno+4(%edi)
 510.endm
 511
 512        set_early_handler handler=early_divide_err,trapno=0
 513        set_early_handler handler=early_illegal_opcode,trapno=6
 514        set_early_handler handler=early_protection_fault,trapno=13
 515        set_early_handler handler=early_page_fault,trapno=14
 516
 517        ret
 518
 519early_divide_err:
 520        xor %edx,%edx
 521        pushl $0        /* fake errcode */
 522        jmp early_fault
 523
 524early_illegal_opcode:
 525        movl $6,%edx
 526        pushl $0        /* fake errcode */
 527        jmp early_fault
 528
 529early_protection_fault:
 530        movl $13,%edx
 531        jmp early_fault
 532
 533early_page_fault:
 534        movl $14,%edx
 535        jmp early_fault
 536
 537early_fault:
 538        cld
 539#ifdef CONFIG_PRINTK
 540        pusha
 541        movl $(__KERNEL_DS),%eax
 542        movl %eax,%ds
 543        movl %eax,%es
 544        cmpl $2,early_recursion_flag
 545        je hlt_loop
 546        incl early_recursion_flag
 547        movl %cr2,%eax
 548        pushl %eax
 549        pushl %edx              /* trapno */
 550        pushl $fault_msg
 551#ifdef CONFIG_EARLY_PRINTK
 552        call early_printk
 553#else
 554        call printk
 555#endif
 556#endif
 557        call dump_stack
 558hlt_loop:
 559        hlt
 560        jmp hlt_loop
 561
 562/* This is the default interrupt "handler" :-) */
 563        ALIGN
 564ignore_int:
 565        cld
 566#ifdef CONFIG_PRINTK
 567        pushl %eax
 568        pushl %ecx
 569        pushl %edx
 570        pushl %es
 571        pushl %ds
 572        movl $(__KERNEL_DS),%eax
 573        movl %eax,%ds
 574        movl %eax,%es
 575        cmpl $2,early_recursion_flag
 576        je hlt_loop
 577        incl early_recursion_flag
 578        pushl 16(%esp)
 579        pushl 24(%esp)
 580        pushl 32(%esp)
 581        pushl 40(%esp)
 582        pushl $int_msg
 583#ifdef CONFIG_EARLY_PRINTK
 584        call early_printk
 585#else
 586        call printk
 587#endif
 588        addl $(5*4),%esp
 589        popl %ds
 590        popl %es
 591        popl %edx
 592        popl %ecx
 593        popl %eax
 594#endif
 595        iret
 596
 597.section .cpuinit.data,"wa"
 598.align 4
 599ENTRY(initial_code)
 600        .long i386_start_kernel
 601
 602.section .text
 603/*
 604 * Real beginning of normal "text" segment
 605 */
 606ENTRY(stext)
 607ENTRY(_stext)
 608
 609/*
 610 * BSS section
 611 */
 612.section ".bss.page_aligned","wa"
 613        .align PAGE_SIZE_asm
 614#ifdef CONFIG_X86_PAE
 615swapper_pg_pmd:
 616        .fill 1024*KPMDS,4,0
 617#else
 618ENTRY(swapper_pg_dir)
 619        .fill 1024,4,0
 620#endif
 621swapper_pg_fixmap:
 622        .fill 1024,4,0
 623ENTRY(empty_zero_page)
 624        .fill 4096,1,0
 625/*
 626 * This starts the data section.
 627 */
 628#ifdef CONFIG_X86_PAE
 629.section ".data.page_aligned","wa"
 630        /* Page-aligned for the benefit of paravirt? */
 631        .align PAGE_SIZE_asm
 632ENTRY(swapper_pg_dir)
 633        .long   pa(swapper_pg_pmd+PGD_IDENT_ATTR),0     /* low identity map */
 634# if KPMDS == 3
 635        .long   pa(swapper_pg_pmd+PGD_IDENT_ATTR),0
 636        .long   pa(swapper_pg_pmd+PGD_IDENT_ATTR+0x1000),0
 637        .long   pa(swapper_pg_pmd+PGD_IDENT_ATTR+0x2000),0
 638# elif KPMDS == 2
 639        .long   0,0
 640        .long   pa(swapper_pg_pmd+PGD_IDENT_ATTR),0
 641        .long   pa(swapper_pg_pmd+PGD_IDENT_ATTR+0x1000),0
 642# elif KPMDS == 1
 643        .long   0,0
 644        .long   0,0
 645        .long   pa(swapper_pg_pmd+PGD_IDENT_ATTR),0
 646# else
 647#  error "Kernel PMDs should be 1, 2 or 3"
 648# endif
 649        .align PAGE_SIZE_asm            /* needs to be page-sized too */
 650#endif
 651
 652.data
 653ENTRY(stack_start)
 654        .long init_thread_union+THREAD_SIZE
 655        .long __BOOT_DS
 656
 657ready:  .byte 0
 658
 659early_recursion_flag:
 660        .long 0
 661
 662int_msg:
 663        .asciz "Unknown interrupt or fault at EIP %p %p %p\n"
 664
 665fault_msg:
 666/* fault info: */
 667        .ascii "BUG: Int %d: CR2 %p\n"
 668/* pusha regs: */
 669        .ascii "     EDI %p  ESI %p  EBP %p  ESP %p\n"
 670        .ascii "     EBX %p  EDX %p  ECX %p  EAX %p\n"
 671/* fault frame: */
 672        .ascii "     err %p  EIP %p   CS %p  flg %p\n"
 673        .ascii "Stack: %p %p %p %p %p %p %p %p\n"
 674        .ascii "       %p %p %p %p %p %p %p %p\n"
 675        .asciz "       %p %p %p %p %p %p %p %p\n"
 676
 677#include "../../x86/xen/xen-head.S"
 678
 679/*
 680 * The IDT and GDT 'descriptors' are a strange 48-bit object
 681 * only used by the lidt and lgdt instructions. They are not
 682 * like usual segment descriptors - they consist of a 16-bit
 683 * segment size, and 32-bit linear address value:
 684 */
 685
 686.globl boot_gdt_descr
 687.globl idt_descr
 688
 689        ALIGN
 690# early boot GDT descriptor (must use 1:1 address mapping)
 691        .word 0                         # 32 bit align gdt_desc.address
 692boot_gdt_descr:
 693        .word __BOOT_DS+7
 694        .long boot_gdt - __PAGE_OFFSET
 695
 696        .word 0                         # 32-bit align idt_desc.address
 697idt_descr:
 698        .word IDT_ENTRIES*8-1           # idt contains 256 entries
 699        .long idt_table
 700
 701# boot GDT descriptor (later on used by CPU#0):
 702        .word 0                         # 32 bit align gdt_desc.address
 703ENTRY(early_gdt_descr)
 704        .word GDT_ENTRIES*8-1
 705        .long per_cpu__gdt_page         /* Overwritten for secondary CPUs */
 706
 707/*
 708 * The boot_gdt must mirror the equivalent in setup.S and is
 709 * used only for booting.
 710 */
 711        .align L1_CACHE_BYTES
 712ENTRY(boot_gdt)
 713        .fill GDT_ENTRY_BOOT_CS,8,0
 714        .quad 0x00cf9a000000ffff        /* kernel 4GB code at 0x00000000 */
 715        .quad 0x00cf92000000ffff        /* kernel 4GB data at 0x00000000 */
 716
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.