The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/i386/i386/mpboot.s

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1995 Jack F. Vogel
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  *
   26  * mpboot.s:    FreeBSD machine support for the Intel MP Spec
   27  *              multiprocessor systems.
   28  *
   29  * $FreeBSD$
   30  */
   31 
   32 #include "opt_pmap.h"
   33 
   34 #include <machine/asmacros.h>           /* miscellaneous asm macros */
   35 #include <x86/apicreg.h>
   36 #include <machine/specialreg.h>
   37 
   38 #include "assym.inc"
   39 
   40 /*
   41  * this code MUST be enabled here and in mp_machdep.c
   42  * it follows the very early stages of AP boot by placing values in CMOS ram.
   43  * it NORMALLY will never be needed and thus the primitive method for enabling.
   44  *
   45 #define CHECK_POINTS
   46  */
   47 
   48 #if defined(CHECK_POINTS)
   49 
   50 #define CMOS_REG        (0x70)
   51 #define CMOS_DATA       (0x71)
   52 
   53 #define CHECKPOINT(A,D)         \
   54         movb    $(A),%al ;      \
   55         outb    %al,$CMOS_REG ; \
   56         movb    $(D),%al ;      \
   57         outb    %al,$CMOS_DATA
   58 
   59 #else
   60 
   61 #define CHECKPOINT(A,D)
   62 
   63 #endif /* CHECK_POINTS */
   64 
   65 
   66 /*
   67  * the APs enter here from their trampoline code (bootMP, below)
   68  */
   69         .p2align 4
   70 
   71 NON_GPROF_ENTRY(MPentry)
   72         CHECKPOINT(0x36, 3)
   73         /*
   74          * Enable features on this processor.  We don't support SMP on
   75          * CPUs older than a Pentium, so we know that we can use the cpuid
   76          * instruction.
   77          */
   78         movl    $1,%eax
   79         cpuid                                   /* Retrieve features */
   80         movl    %cr4,%eax
   81         testl   $CPUID_PSE,%edx
   82         jz 1f
   83         orl     $CR4_PSE,%eax                   /* Enable PSE  */
   84 1:      testl   $CPUID_PGE,%edx
   85         jz 2f
   86         orl     $CR4_PGE,%eax                   /* Enable PGE  */
   87 2:      testl   $CPUID_VME,%edx
   88         jz 3f
   89         orl     $CR4_VME,%eax                   /* Enable VME  */
   90 3:      movl    %eax,%cr4
   91 
   92         /* Now enable paging mode */
   93         cmpl    $0, pae_mode
   94         je      4f
   95         movl    IdlePDPT, %eax
   96         movl    %eax, %cr3
   97         movl    %cr4, %eax
   98         orl     $CR4_PAE, %eax
   99         movl    %eax, %cr4
  100         movl    $0x80000000, %eax
  101         cpuid
  102         movl    $0x80000001, %ebx
  103         cmpl    %ebx, %eax
  104         jb      5f
  105         movl    %ebx, %eax
  106         cpuid
  107         testl   $AMDID_NX, %edx
  108         je      5f
  109         movl    $MSR_EFER, %ecx
  110         rdmsr
  111         orl     $EFER_NXE,%eax
  112         wrmsr
  113         jmp     5f
  114 4:      movl    IdlePTD_nopae, %eax
  115         movl    %eax,%cr3       
  116 5:      movl    %cr0,%eax
  117         orl     $CR0_PE|CR0_PG,%eax             /* enable paging */
  118         movl    %eax,%cr0                       /* let the games begin! */
  119         movl    bootSTK,%esp                    /* boot stack end loc. */
  120 
  121         pushl   $mp_begin                       /* jump to high mem */
  122         ret
  123 
  124         /*
  125          * Wait for the booting CPU to signal startup
  126          */
  127 mp_begin:       /* now running relocated at KERNBASE */
  128         CHECKPOINT(0x37, 4)
  129         call    init_secondary                  /* load i386 tables */
  130 
  131 /*
  132  * This is the embedded trampoline or bootstrap that is
  133  * copied into 'real-mode' low memory, it is where the
  134  * secondary processor "wakes up". When it is executed
  135  * the processor will eventually jump into the routine
  136  * MPentry, which resides in normal kernel text above
  137  * 1Meg.                -jackv
  138  */
  139 
  140         .data
  141         ALIGN_DATA                              /* just to be sure */
  142 
  143 BOOTMP1:
  144 
  145 NON_GPROF_ENTRY(bootMP)
  146         .code16         
  147         cli
  148         CHECKPOINT(0x34, 1)
  149         /* First guarantee a 'clean slate' */
  150         xorl    %eax, %eax
  151         movl    %eax, %ebx
  152         movl    %eax, %ecx
  153         movl    %eax, %edx
  154         movl    %eax, %esi
  155         movl    %eax, %edi
  156 
  157         /* set up data segments */
  158         mov     %cs, %ax
  159         mov     %ax, %ds
  160         mov     %ax, %es
  161         mov     %ax, %fs
  162         mov     %ax, %gs
  163         mov     %ax, %ss
  164         mov     $(boot_stk-bootMP), %esp
  165 
  166         /* Now load the global descriptor table */
  167         lgdt    MP_GDTptr-bootMP
  168 
  169         /* Enable protected mode */
  170         movl    %cr0, %eax
  171         orl     $CR0_PE, %eax
  172         movl    %eax, %cr0 
  173 
  174         /*
  175          * make intrasegment jump to flush the processor pipeline and
  176          * reload CS register
  177          */
  178         pushl   $0x18
  179         pushl   $(protmode-bootMP)
  180         lretl
  181 
  182        .code32          
  183 protmode:
  184         CHECKPOINT(0x35, 2)
  185 
  186         /*
  187          * we are NOW running for the first time with %eip
  188          * having the full physical address, BUT we still
  189          * are using a segment descriptor with the origin
  190          * not matching the booting kernel.
  191          *
  192          * SO NOW... for the BIG Jump into kernel's segment
  193          * and physical text above 1 Meg.
  194          */
  195         mov     $0x10, %ebx
  196         movw    %bx, %ds
  197         movw    %bx, %es
  198         movw    %bx, %fs
  199         movw    %bx, %gs
  200         movw    %bx, %ss
  201 
  202         .globl  bigJump
  203 bigJump:
  204         /* this will be modified by mpInstallTramp() */
  205         ljmp    $0x08, $0                       /* far jmp to MPentry() */
  206         
  207 dead:   hlt /* We should never get here */
  208         jmp     dead
  209 
  210 /*
  211  * MP boot strap Global Descriptor Table
  212  */
  213         .p2align 4
  214         .globl  MP_GDT
  215         .globl  bootCodeSeg
  216         .globl  bootDataSeg
  217 MP_GDT:
  218 
  219 nulldesc:               /* offset = 0x0 */
  220 
  221         .word   0x0     
  222         .word   0x0     
  223         .byte   0x0     
  224         .byte   0x0     
  225         .byte   0x0     
  226         .byte   0x0     
  227 
  228 kernelcode:             /* offset = 0x08 */
  229 
  230         .word   0xffff  /* segment limit 0..15 */
  231         .word   0x0000  /* segment base 0..15 */
  232         .byte   0x0     /* segment base 16..23; set for 0K */
  233         .byte   0x9f    /* flags; Type  */
  234         .byte   0xcf    /* flags; Limit */
  235         .byte   0x0     /* segment base 24..32 */
  236 
  237 kerneldata:             /* offset = 0x10 */
  238 
  239         .word   0xffff  /* segment limit 0..15 */
  240         .word   0x0000  /* segment base 0..15 */
  241         .byte   0x0     /* segment base 16..23; set for 0k */
  242         .byte   0x93    /* flags; Type  */
  243         .byte   0xcf    /* flags; Limit */
  244         .byte   0x0     /* segment base 24..32 */
  245 
  246 bootcode:               /* offset = 0x18 */
  247 
  248         .word   0xffff  /* segment limit 0..15 */
  249 bootCodeSeg:            /* this will be modified by mpInstallTramp() */
  250         .word   0x0000  /* segment base 0..15 */
  251         .byte   0x00    /* segment base 16...23; set for 0x000xx000 */
  252         .byte   0x9e    /* flags; Type  */
  253         .byte   0xcf    /* flags; Limit */
  254         .byte   0x0     /*segment base 24..32 */
  255 
  256 bootdata:               /* offset = 0x20 */
  257 
  258         .word   0xffff  
  259 bootDataSeg:            /* this will be modified by mpInstallTramp() */
  260         .word   0x0000  /* segment base 0..15 */
  261         .byte   0x00    /* segment base 16...23; set for 0x000xx000 */
  262         .byte   0x92    
  263         .byte   0xcf    
  264         .byte   0x0             
  265 
  266 /*
  267  * GDT pointer for the lgdt call
  268  */
  269         .globl  mp_gdtbase
  270 
  271 MP_GDTptr:      
  272 mp_gdtlimit:
  273         .word   0x0028          
  274 mp_gdtbase:             /* this will be modified by mpInstallTramp() */
  275         .long   0
  276 
  277         .space  0x100   /* space for boot_stk - 1st temporary stack */
  278 boot_stk:
  279 
  280 BOOTMP2:
  281         .globl  bootMP_size
  282 bootMP_size:
  283         .long   BOOTMP2 - BOOTMP1

Cache object: ce709d762619604b853564ef9af76d50


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.